An Azure service that provides a hybrid, multi-cloud management platform for APIs.
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:
- 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. - 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.).
- 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
- 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. - 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.
- 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. - If you need guaranteed large-payload handling, avoid relying on buffering behavior at all. Use the
Content-Lengthheader 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