You deploy gpt-5.1 in East US, wire it into the app, and the first real load test returns HTTP 429 with a Retry-After header on the fifth concurrent request. The deployment is healthy. The subscription quota for that model, in that region, is not, and no amount of retry logic raises a ceiling you never asked for.
Quota on Azure OpenAI is not one number. It is a grid. There is a separate pool for every model, in every region, under every subscription, and it splits again by deployment type. Miss that shape and you either stand up six resources you never needed, or you promise a launch date your ceiling cannot hold. This part maps the grid, gives the real 2026 numbers, explains the quota tier change that landed this year, and ends with the two commands I run before I commit to any capacity.
Three scopes for one model
Start with the two units everything is measured in. Tokens per minute, written TPM, is the rate of prompt plus response tokens the service will accept before it throttles. Requests per minute, written RPM, is the count of API calls in the same window. Azure enforces both, and you can trip the RPM limit while TPM still looks idle, or the reverse.
The highest boundary is the Azure subscription. Quota is not pooled across your tenant, so two subscriptions under the same billing account get two independent grids. Inside a subscription, each region carries its own pool. gpt-5.1 in East US and gpt-5.1 in Sweden Central draw from separate buckets that never share. Inside a region, the pool is split per model, then split again per deployment type, so Global Standard and Data Zone Standard of the same model do not borrow from each other.
That is four dimensions before you write a line of code: subscription, region, model, deployment type. Every capacity conversation I have starts by naming all four, because a quota number without them is meaningless.
How is quota actually counted?
Here are the numbers a Tier 1 subscription starts with in 2026. These are the defaults Microsoft publishes on the quotas and limits page, and Global Standard almost always carries the highest ceiling because it routes across the whole Azure footprint.
| Model | Deployment type | RPM | TPM |
|---|---|---|---|
| gpt-5.1 | Global Standard | 10,000 | 1,000,000 |
| gpt-5.1 | Data Zone Standard | 3,000 | 300,000 |
| gpt-5.1 | Standard (regional) | 3,000 | 300,000 |
| gpt-4.1 | Global Standard | 1,000 | 1,000,000 |
| gpt-4o-mini | Global Standard | 20,000 | 2,000,000 |
Tier 1 defaults from the Azure OpenAI quotas and limits page. RPM and TPM both apply; you can hit either first.
Quota tiers and the auto-upgrade shift
Microsoft replaced the old Default and Enterprise quota levels with Quota Tiers. There is a Free Tier and then Tiers 1 through 6, where Tier 6 holds the highest ceilings. Your starting tier depends on current usage of that model and your relationship with Microsoft, so an Enterprise Agreement or MCA-E account lands higher than a fresh pay-as-you-go subscription.
The part that changes day-to-day operations is automatic movement between tiers. As sustained consumption grows and your current tier starts to constrain you, the platform upgrades you to the next tier without a support ticket. Any quota increase you were already granted is kept, never reduced. You can still submit the quota request form to ask for more inside your tier.
There is a catch worth knowing. Some teams use quota as a billing brake, capping spend by capping tokens. Auto-upgrade defeats that. If that describes you, set the tier upgrade policy to NoAutoUpgrade on the subscription and stay put. It is a preview control, so treat it as something to re-check, not set once and forget.
Spread regions to raise your ceiling
Because each region carries its own pool, the fastest way to more headroom is often not a bigger tier. It is a second region. Deploy the same model in two regions under one subscription and you have two full pools to load balance across. This is the lever most teams reach for last when it should be near the front.
It is not free of cost. Two regions means two endpoints, a routing layer in front, and data landing in two geographies, which matters the moment residency is on the table. Global Standard already routes globally, so if you have no residency constraint, raising the tier or moving to provisioned throughput is cleaner. Spread regions when Data Zone or regional deployments have pinned you and you still need more rate.
Worked example
A retrieval app peaks at 1,800,000 TPM on gpt-5.1. One Tier 1 Global Standard region gives 1,000,000, which throttles at peak. Options: request an increase inside the tier, wait for auto-upgrade to Tier 2, or deploy the same model in a second region for 2,000,000 combined and route across both today. I take the second region when the launch date is fixed, then let the tier climb catch up and retire the extra region if it turns out I do not need it.
What do data zones change?
A data zone is a middle ground between global routing and a single region. Global deployments may process a prompt in any Azure geography where the model runs. A Data Zone deployment keeps inference inside one Microsoft-defined zone, either the United States or the European Union. Regional Standard pins inference to the exact region your resource lives in, which is the strongest residency guarantee and usually the smallest quota.
The EU zone processes data inside the Azure EU Data Boundary. As of May 2026 that covers regions in France, Germany, Italy, Netherlands, Norway, Poland, Spain, Sweden, and Switzerland, and Microsoft can add more without notice to keep capacity healthy. Data at rest stays in your chosen geography under every option; the zone choice only governs where inference runs.
| Deployment | Inference runs | Quota pool | Best for |
|---|---|---|---|
| Global Standard | Any Azure geography | Highest default | No residency rule |
| Data Zone Standard | Within US or EU zone | Per zone, mid | US or EU compliance |
| Standard (regional) | Single region only | Smallest, per region | Strict single-region rule |
SKU codes in the API are GlobalStandard, DataZoneStandard, and Standard. Provisioned variants add Global and Data Zone flavors too.
One more field note on regions. Model availability is not uniform across Azure, so the newest models reach a handful of regions first and widen out over the following weeks. Pick your region for the model you need today and the residency you owe, then confirm that model is actually offered there before you commit it to a design. A region with plenty of quota and no deployment of your model is worth nothing to you.
Resource and deployment limits you plan around
Quota is the rate ceiling. There is a second set of limits on how many objects you can create, and on a large estate they bite before TPM does. Azure caps you at 30 Azure OpenAI resources per region per subscription, and each resource holds up to 32 standard deployments. Fine-tuned model deployments are capped at 10 per resource.
Those numbers sound generous until you multiply. A team that gives every product its own resource for isolation, across three regions, burns through the per-region resource count faster than anyone expected, and the fix is a redesign rather than a support ticket. I keep deployments consolidated per resource and spin up separate resources only for a real blast-radius or billing boundary, not for tidiness. Group deployments by the residency and quota profile they share, because that is what actually differs between them.
Provisioned throughput lives in its own quota, counted in provisioned throughput units rather than tokens per minute, and one deployment can hold up to 100,000 units. Reserve that capacity separately from your standard pools; the two never trade. Part 6 covers when a reservation earns its keep.
Why a 429 shows up below your quota
The confusing failure is a 429 while the token dashboard still looks calm. It happens because RPM and TPM are enforced independently, and many models smooth the limit over a short window instead of a full minute. A burst of small requests can drain the request budget inside a two or three second slice even though your minute-level token count sits nowhere near the ceiling. The service is guarding the same shared pool, just on a finer clock.
Two habits keep this out of production. Retry with exponential backoff and honor the Retry-After header instead of hammering, because a tight retry loop makes the throttle worse. Then smooth your own traffic. Ramp load gradually rather than opening the taps, since a sharp step change reads as an attack on the rate limiter and earns you more 429s.
Batch is the pressure valve for volume that is not time sensitive. Global Batch and Data Zone Batch carry a separate enqueued token quota, so a large asynchronous job runs without touching the online pool your live traffic depends on. When a nightly summarization run was starving daytime chat, moving it to batch fixed both problems at once.
Check quota before you promise a launch date
Two things decide whether you can ship: which tier your subscription sits in, and how much capacity is actually free in the region you want. The Foundry portal shows both under Quota, but I script the tier check so it goes in a runbook. This calls the control plane and prints your assigned tier for the subscription.
TOKEN=$(az account get-access-token --resource https://management.azure.com --query accessToken -o tsv)
curl -s
'https://management.azure.com/subscriptions/<SUB_ID>/providers/Microsoft.CognitiveServices/quotaTiers?api-version=2025-10-01-preview'
-H "Authorization: Bearer $TOKEN" | jq .Expected output: a JSON body describing the subscription tier for each model, so you can confirm you are on Tier 1 or higher before quoting a rate to anyone. The exact property names are still moving under the preview API, so read the returned keys rather than hard-coding them [VERIFY].
Failure mode: a 401 means the access token was minted for the wrong resource or has expired; re-run the az line. A 403 means your identity lacks Reader on the subscription, so no networking or firewall change will fix it, only a role assignment will. To pin a subscription and stop auto-upgrade, PATCH the same quotaTiers path with a body setting tierUpgradePolicy to NoAutoUpgrade.
Start data zone, add regions before you add complexity
Here is where I would start. If you have no residency rule, use Global Standard and let its higher ceiling and global routing carry you; only reach for provisioned throughput when latency variance under load becomes the problem. If you owe the EU or US a data boundary, start on Data Zone Standard and accept the lower default, then buy headroom with a second region in the same zone before you touch anything more complicated. Keep single-region Standard for the narrow case where a contract names one region and nothing else will do.
Validate two things before you commit a date. Confirm the tier with the command above, and confirm real capacity in your target region through the portal, because a published default is not a promise of free capacity on the day you deploy. Leave auto-upgrade on for products and off for shared sandboxes.
You now have the rate ceiling mapped. The next question is how traffic reaches these endpoints without crossing the public internet, which is Part 9 on Private Link and virtual networks. If you run AWS as well, the same grid logic and cross-region trick appears in the Bedrock regions and quotas part. Before you deploy anything wider, run the tier check and screenshot your region capacity.
References
- Azure OpenAI in Microsoft Foundry Models quotas and limits
- Deployment types for Microsoft Foundry Models
- Announcing the availability of Azure OpenAI Data Zones


DrJha