Does the 2 MiB request body buffering limit still apply to the Standard v2 gateway when using context.Request.Body.As<string>()?

舩山 20 Reputation points
2026-08-01T06:21:50.2133333+00:00

Hello,

I have a question regarding the request body buffering limit in Azure API Management.

I found the following Microsoft Q&A answer stating that APIM has a 2 MiB limit when a policy reads or modifies the request/response body (for example, using context.Request.Body or set-body):

https://learn.microsoft.com/en-us/answers/questions/5787833/json-payload-limit-in-azure-apim

The answer states:

"2 MiB on all tiers. This is the key limit when policies need to read or modify the request/response body using context.Request.Body or set-body."

However, I cannot reproduce this behavior on my environment.

Environment Azure API Management Standard v2 Gateway: Managed gateway Request body: JSON (approximately 10 MB) Policy

I configured the following inbound policy:

<policies>
  <inbound>
    <base />
    <set-variable name="body"
        value="@(context.Request.Body.As<string>(preserveContent: true))" />
  </inbound>
  <backend>
    <base />
  </backend>
  <outbound>
    <base />
  </outbound>
</policies>

I then sent a 10 MB JSON request body to the API.

Result

The request completed successfully:

HTTP 200 OK The request reached the backend successfully. context.Request.Body.As<string>(preserveContent: true) did not produce any exception. Questions Does the 2 MiB buffering limit still apply to the Standard v2 gateway? Is the 2 MiB limit only applicable to the Classic gateway, or has the implementation changed in v2? Is there any official documentation describing the current maximum request/response body size that can be buffered by policy expressions such as context.Request.Body.As<string>()?

Thank you.

Azure API Management
Azure API Management

An Azure service that provides a hybrid, multi-cloud management platform for APIs.

0 comments No comments

Answer accepted by question author

Jerald Felix 17,640 Reputation points Volunteer Moderator
2026-08-01T17:16:51.0233333+00:00

Hello 舩山,

Greetings! Thanks for raising this question in the Q&A forum.

Good catch, and this is worth clarifying because the earlier answer you referenced is now out of date on one detail. Here is the current, verified picture.

Root cause

According to Microsoft's current API Management gateway runtime limits table, the buffered payload size is not "2 MiB on all tiers" anymore. The documented values are:

Runtime limit Classic V2 Consumption
Buffered payload size 500 MiB 2 MiB 2 MiB
-------- -------- -------- --------
Buffered payload size 500 MiB 2 MiB 2 MiB
Request payload size Unlimited 1 GiB 1 GiB

So the 2 MiB buffered payload limit does still officially apply to Standard v2, Basic v2, and Premium v2, same as Consumption. It's the Classic tier that changed, and it's now documented at 500 MiB, not 2 MiB. That's likely where the discrepancy with the older thread comes from, since Classic used to be documented differently and that answer predates this revision.

Why your 10 MB test didn't throw an exception

This is the more interesting part, because your test result does genuinely conflict with the documented 2 MiB figure for v2. A few possibilities, roughly in order of likelihood:

  1. Enforcement inconsistency between buffering paths. The documented "buffered payload size" limit appears to primarily govern internal gateway buffering behavior for streaming/pass-through scenarios. Explicit calls like context.Request.Body.As<string>(preserveContent: true) may follow a different internal code path that isn't strictly bound by the same enforcement point, so it can succeed even when the documented ceiling would suggest otherwise.
  2. Gradual or SKU-specific rollout. Limits documented at the platform level don't always get enforced identically across every v2 gateway build at the same time. Your specific instance may simply not be enforcing this particular ceiling yet, or may enforce it only under certain conditions (concurrent load, other policies stacked in the pipeline, etc.).
  3. Soft limit vs hard limit. Not everything in that table is a hard-enforced boundary that throws immediately at the byte. Some are closer to "supported design targets" than a strict validation check.

What I'd recommend

  1. Don't design around the fact that it currently works. Since your result contradicts the documented limit, treat 2 MiB as the number to design against for anything going through context.Request.Body.As<string>() on Standard v2. Relying on unenforced headroom is risky since Microsoft could tighten enforcement without notice, since the documented number is what they've committed to.
  2. Test at the boundary to characterize actual behavior. Send payloads at 2 MiB, 5 MiB, 10 MiB, and 50 MiB and record whether/when you get a 403, a timeout, a silent truncation, or continued success. This tells you whether it's unenforced entirely or has a different real ceiling.
  3. Open a support request for a definitive answer. Because this contradicts published documentation, it's worth getting Microsoft's product team to confirm in writing what actually governs your specific Standard v2 instance. Reference your subscription ID, APIM service name/ID, the exact policy XML you used, and the test result (10 MB payload, 200 OK, no exception). Ask specifically whether the 2 MiB buffered payload limit is enforced for context.Request.Body.As<string>() on Standard v2 gateways, since the docs and your observed behavior disagree.
  4. If you need guaranteed large-payload handling, avoid relying on buffering behavior at all. Use the Content-Length header check pattern (no buffering required) or route large payloads to a backend that performs the transformation outside APIM, as noted in the earlier thread.

If this answer helps you kindly accept the answer which will help others who have similar questions.

Best Regards,

Jerald Felix

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.