GPU Quota and Capacity on Azure: What Nobody Tells You Before You Plan
On Azure, GPU availability is a three-dimensional problem, and quota is not the same thing as capacity. The constraint that most often forces an architecture redesign, and how to plan around it.
The architecture is finished. The region was chosen for latency to your users, which took a week of argument and a spreadsheet. The Terraform is written and reviewed. The AKS cluster comes up cleanly.
Then the GPU node pool will not scale, and the error says your subscription has no quota for that VM family in that region.
You open the portal to raise the limit and discover that this is not a slider. It is a support request, it goes to a human, and it has a lead time measured in business days rather than minutes. Meanwhile the demo is on Thursday.
This is the constraint that most often forces an AI platform redesign, and it is the one least likely to appear in a design review. Everybody reviews the model serving architecture. Almost nobody asks whether the hardware in the diagram can actually be obtained in the region the diagram assumes.
Quota is three-dimensional#
The model is simple to state and easy to get wrong in practice. GPU quota on Azure is scoped by three things at once:
- The subscription. Quota does not follow your tenant or your management group. It is granted per subscription.
- The region. Quota granted in one region tells you nothing about any other region.
- The VM family. Quota is granted per family, and a family is narrower than you think.
All three have to line up before a single GPU node comes up. Two out of three is a failed provision.
The part that catches experienced Azure engineers is the third dimension. Most people arrive at GPU quota having already dealt with quota for general purpose compute, where the mental model is "the subscription has a core count and I am using some of it." That model is close enough to true for the everyday case, and it makes GPU quota feel like it should behave the same way. It does not. Approval for one GPU family confers nothing on another family, even one that looks adjacent and serves a similar purpose. They are separate buckets, requested separately and granted separately.
[VERIFY: whether GPU quota is expressed as vCPU cores per family or as VM instance counts currently, and whether the unit differs between families]
The second surprise is the starting position. General purpose compute quota on a new subscription starts at some usable number and you grow into it. GPU quota does not work that way.
[VERIFY: whether GPU quota defaults to zero on new subscriptions currently, and whether this differs by subscription type such as EA, CSP, or pay-as-you-go]
If that default is zero, and it has been for most subscription types in my experience, then this is not a limit you grow into. It is a gate you have to open deliberately before you can do anything at all. Nothing tells you this in advance. The subscription looks healthy, the region is listed, the SKU appears in the portal picker, and the first sign of trouble is a scale operation failing after everything else already worked.
There is also a distinction worth checking before you plan a spot strategy on top of all this.
[VERIFY: whether spot and low-priority GPU quota is a separate bucket from standard quota, per family and per region]
Quota is granted to the subscription, which means it is a shared resource between every team using that subscription. If your platform team and a data science team both consume the same GPU family in the same region, one team's experiment can exhaust the pool the other team's production workload was sized against. Quota consumption belongs on a dashboard that both teams can see, before it belongs in an incident review.
Quota is not capacity#
This is the part that surprises people most, and it is the reason a quota approval email is not the end of the problem.
Quota is permission to allocate. Capacity is whether the hardware is physically there when you ask. They are separate systems. You can hold the first and be refused by the second.
The practical consequence is that a granted quota request does not guarantee you can provision. You can be approved for a family in a region, submit a scale operation, and get an allocation failure, because the region has no free hardware of that type at that moment. Your quota is intact. Your request still failed. Nothing is misconfigured and there is nothing to fix.
This is worst exactly where it hurts most. The newest and most in demand GPU families are the most likely to be capacity constrained, and they are the ones people want, because they are why the project exists.
The failure modes are the useful part of that picture, because they are what you will actually see in a terminal, and they need different responses. A quota error means raise a request and wait. A SKU that is not offered in the region means change region or change family, and no amount of waiting helps. An allocation failure means the request was legitimate and the answer was still no, so retry, try another zone, try another family, or wait for capacity to free up.
Teams routinely misread the third as the first. An allocation failure gets escalated as a quota problem, a quota increase is approved because quota was never the issue, and the scale operation fails again with the same error. That round trip costs days.
What this means for planning is uncomfortable. Your capacity plan has to account for the possibility that quota you hold is unusable at the moment you need it, and that moment is usually a demand spike, which is correlated with everyone else in the region wanting the same hardware for the same reason. Capacity is not reserved for you by being approved for you.
Approved quota is a claim you are permitted to make, not a reservation. If your scaling story depends on adding GPU nodes at the moment traffic arrives, you are depending on regional capacity being free at exactly the time it is most contended. Either hold the capacity in advance or design the workload to degrade rather than to scale.
Regional availability#
Not every GPU family exists in every region, and the distribution does not track region size, age, or commercial importance in any way you can predict from the outside. A large, long established region can lack a family that a smaller one has. This is a function of where the hardware was physically installed, and it changes as fleets are built out.
[VERIFY: current GPU family regional distribution. This changes frequently, so the post should frame it as a check to run rather than a list to trust. Confirm the Azure regional availability page and the SKU list per region at time of publishing.]
The architectural consequence is the real point. Your region choice may end up dictated by which GPUs you can obtain rather than by proximity to users, data residency preference, or an existing footprint.
When those pull in different directions, the GPU constraint usually wins, because the alternative to accepting it is not running at all. That ordering is worth stating plainly in a design document, because it is the opposite of how region selection is normally reasoned about, and someone will otherwise reopen the decision every quarter.
For regulated or sovereignty constrained deployments the collision is sharper. The set of permissible regions is already small before GPU availability narrows it, and the intersection of "we are allowed to run here" and "the hardware we need is sold here" can be a single region, or occasionally none. Discovering that late is how a compliance driven programme ends up with an architecture nobody wanted, because the only workable option was found under time pressure.
[VERIFY: whether GPU family availability differs within a region by availability zone, and whether zonal pinning affects allocation success in practice]
The commitment options#
On demand allocation is the least reliable way to get scarce hardware. You are asking for something contended, at an arbitrary moment, with no prior claim. When capacity is tight, that request is the first to be refused.
Azure offers commitment mechanisms that trade flexibility for a stronger claim on capacity.
[VERIFY: current Azure capacity commitment options for GPU workloads, their exact names, available terms, which GPU families they cover, and critically whether each one carries an allocation guarantee or only a billing discount]
The general shape is worth understanding even before the specifics are confirmed, because it changes how you should think about the decision. A commitment ties you to a term in exchange for a better rate and, more importantly for GPU workloads, a stronger position when capacity is scarce.
That second benefit is usually the real reason to commit, and it inverts how reserved capacity is normally pitched. In the general compute case, you commit because the discount is worth the loss of flexibility, and availability is not in question. For scarce GPU families the discount is close to a secondary consideration. You are buying the ability to provision at all on a day when on demand requests are being refused.
The tension is genuine and there is no clever way around it. Committing requires you to forecast demand for a workload type whose demand is famously hard to forecast, over a term long enough for your model and your architecture to change. Unused commitment is pure waste, at GPU prices.
The way through is usually to split the workload. Commit to the floor, meaning the baseline you are confident you will run continuously for the term, and leave the variable portion on demand while accepting that it is the part that may be refused. That gives you a guaranteed base and an honest view of which part of your capacity is speculative.
What this means for how you plan#
Five things follow, and the first one matters more than the other four combined.
Request quota before you design, not after. The lead time on a quota request means it should start at the same time as the architecture work, not at the end of it. Most teams get this backwards: they design, they build, they hit the wall, and then they wait, with the whole project blocked on a support queue. Submitting requests during the design phase costs almost nothing and removes the single most common source of schedule slip in AI infrastructure projects. If you take one thing from this post, take this one.
[VERIFY: current typical lead time for GPU quota requests, and whether it differs by subscription type, region, or requested size]
Request in more regions than you plan to use. The marginal cost of another quota request is one more support ticket. The cost of discovering your chosen region cannot serve you is a redesign under time pressure, after commitments have been made to stakeholders. Request in your primary region and at least one credible alternative. It is the cheapest insurance in the project.
Design for more than one GPU family. If your platform only works on one family, its availability is bounded by the scarcest link in the chain, and you have no move when that link fails. Being able to fall back to an older or otherwise different family, even at a real performance cost, is worth substantially more than it appears on a capacity plan. A workload running at 70% of intended throughput is a performance problem. A workload that cannot be placed is an outage. The engineering to keep that option open, meaning not pinning to family specific features or hard coding SKU names through your infrastructure code, is cheap if you do it from the start and expensive to retrofit.
Treat region as a variable, not a given. When GPU availability and user latency conflict, model the actual cost of each rather than defending the original choice. The added latency of a further region is frequently smaller than assumed, and much smaller than the cost of having no hardware. Put a number on it before the argument becomes positional.
Distinguish quota planning from capacity planning. They are different exercises with different failure modes and both need doing. Quota planning asks whether you are permitted to allocate what your growth curve implies, and it is solved with paperwork and lead time. Capacity planning asks whether the hardware will be free when you reach for it, and it is solved with commitments, multi region flexibility, and a workload that degrades rather than falls over. A team that has done only the first will be surprised at the worst possible moment, and will usually describe the surprise as a quota problem.
The constraint that comes first#
On most cloud infrastructure, the constraint you plan around is cost or performance. You assume the resource is obtainable and optimise how much you use and how much you pay. That assumption is so reliable it has stopped being an assumption and become a background condition of how architecture is done.
For GPU workloads it does not hold, on any cloud, and Azure makes the seams visible because quota and capacity are so plainly separate systems. The first question is not how fast or how cheap. It is whether the hardware is obtainable at all, in a region you are allowed to use, in a subscription that is permitted to ask for it, at the moment you need it.
Teams that treat that as a procurement detail to be sorted out later end up redesigning. Teams that treat it as an architectural input, on the same page as the model choice and the serving topology, ship on time. The difference is not sophistication. It is what order they asked the questions in.
Running GPU nodes as production infrastructure, including node pool design, scheduling, and the failure modes that follow from scarce hardware, is covered in the Production GPU Infrastructure on Kubernetes course. The commitment and capacity economics side, including how to decide what to commit to and what to leave on demand, is in GPU Cost Optimization on Kubernetes.
More in GPU Infrastructure
DRA Is Stable. The Device Plugin Era Is Ending.
The device plugin API can only count. That single limitation is why your GPU scheduling runs on node labels and pre-partitioned MIG. Dynamic Resource Allocation went GA in Kubernetes 1.34, and in 1.36 the features that make it usable landed. Here is what changes and what to do about it.
Read postYour GPU Dashboard Says 100% Utilized. It's Lying. Welcome to DCGM.
Every post about GPU incidents starts with 'the dashboards looked fine.' That's the problem. nvidia-smi GPU utilization tells you a kernel ran, not whether the silicon is doing work. The metrics that actually matter, the DCGM + Prometheus stack that exposes them, and the queries and alerts that catch real GPU failures.
Read postYour H100 Serves Three Teams Now. MIG or Time-Slicing? Pick Wrong and the Answer Hurts.
MIG is hardware partitioning. Time-slicing is software multiplexing. They are not interchangeable. The production decision walk-through, the H100 profile math, the GPU Operator config, and the migration path most teams hit.
Read post