Azure reservation not applied: do not buy another yet
Trace an Azure VM reservation gap through daily usage, billing scope and size ratios, then decide between rescoping, exchanging and waiting.
On this page
Unused reservation hours expire every hour while eligible VMs without another discount bill at pay-as-you-go rates. Fix the scope or size-group mismatch before buying more, and exchange only when demand has moved to a different region or size for good.
In this illustrative example, three Linux Standard_D4s_v5 VMs in East US bill at the pay-as-you-go retail rate of $0.192 an hour, checked September 26, 2026, while reserved hours that look like a match expire unused. On the Reservations page, the reservation owner sees ten one-year reservations stuck at 70% utilization. The three uncovered VMs add 3 × 24 × $0.192 = $13.82 of compute a day.
The reservation discount is use-it-or-lose-it. With no matching resource in an hour, the reservation quantity for that hour is lost, and unused hours cannot carry forward. Azure applies the discount automatically, and only to usage that matches the reservation's attributes and quantity. An eleventh reservation bought with the same attributes and scope inherits the same mismatch. Each hour's application is locked when the hour ends, and a reservation does not need to be assigned to a VM for the discount to apply, so there is no assignment to fix. The fix starts with the attributes that decide a match: region, instance size flexibility group and billing scope, then quantity, eligibility and reporting delay.
A zero utilization reading can be late data
When Azure receives no usage data for four to eight hours, it calculates utilization as zero percent, so a single low reading does not prove a mismatch. In the portal's Reservations blade, select the reservation's last known utilization percentage to open its history and details. Anyone without billing access can ask the reservation's billing owner for that same history. Wait for the missing usage to land before diagnosing those hours.
An EffectivePrice of zero means something different. In Actual Cost data it marks the usage that received the reservation discount. For wasted commitment, use Amortized Cost and filter ChargeType = UnusedReservation, which returns the daily unused quantity and cost. At 100% utilization that record has a quantity of 0.
Compare daily reserved and used hours across the affected dates. A monthly average hides the day a resource move changed coverage, and the low-utilization alert emails average the last 7 or 30 days, so they cannot say where a particular hour went.
At 70% match, unused reservation cost and on-demand compute coexist
In the example, seven VMs run in the scoped subscription and three run in another subscription inside the same Enterprise Agreement enrollment. Everything else matches, both subscriptions are eligible, and no other commitment competes for the usage.
For a 1-year Standard_D4s_v5 reservation, the same East US Linux retail lookup lists $1,038. Across 8,760 hours in a year, that is approximately $0.11849 per hour. These are retail list prices, not the negotiated rates on an enterprise agreement.
Over 30 days, each VM runs 30 × 24 = 720 hours, so the ten reservations allocate 7,200 × ($1,038 ÷ 8,760) = $853.15 to the period. Use the unrounded hourly fraction and round only the totals.
| Example allocation over 30 days | Current scope | Scope includes all 10 VMs |
|---|---|---|
| Reserved hours used | 5,040 | 7,200 |
| Reserved hours unused | 2,160 | 0 |
| Reservation cost allocated to period | $853.15 | $853.15 |
| Uncovered compute: 3 × 720 × $0.192 | $414.72 | $0.00 |
| Combined compute cost | $1,267.87 | $853.15 |
The unused portion, 2,160 × ($1,038 ÷ 8,760) = $255.95, already sits inside that $853.15 allocation. The reservation commitment costs the same either way, so the sum worth chasing is the $414.72 of uncovered compute at retail list price, or $13.82 for each further day the mismatch stands. Left alone for a year, those three VMs cost $5,045.76. At 200 reservations with the same 30% mismatch, 60 × 8,760 × $0.192 = $100,915.20 a year.
A VM that runs only part of an hour leaves coverage behind, and Azure can fill the rest of that hour from other matching VMs that are not using a reservation, including concurrently running ones.
Shared scope still stops at the billing boundary
A VM moved from Subscription A to Subscription B loses the discount from a reservation scoped to A. Resource-group scope covers the selected group only. Shared scope reaches eligible subscriptions within one billing context: the enrollment for Enterprise Agreement customers, the billing profile for Microsoft Customer Agreement customers. Move a subscription to a different billing context and the benefit stops applying to it.
Management-group scope needs a subscription to sit in both the management group hierarchy and the billing scope. Azure processes scopes in order: single resource group, single subscription, management group, then shared. Check which reservation received the usage before concluding that the shared one failed.
Eligible offers are MS-AZR-0017P and MS-AZR-0148P for Enterprise Agreement, plus MS-AZR-0003P and MS-AZR-0023P for pay-as-you-go. MS-AZR-0148P and MS-AZR-0023P are the Dev/Test offers, and both qualify. Resources running in a subscription on any other offer type receive no reservation discount.
Size ratios explain partial coverage
Region has to match before instance size flexibility matters at all. Inside a flexibility group, a reservation bought at one size applies to every size in the group. It does not follow a VM out of the group: Microsoft's troubleshooting guide shows a D2_v3 reservation no longer applying after a switch to D2s_v3, and sizes listed in different groups, such as DSv2 Series High Memory, cannot share the discount. Check the VM size in AdditionalInfo in the usage file or usage API.
Microsoft's documented example uses Standard_DS4_v2 at ratio 8 and Standard_DS5_v2 at ratio 16. One DS4_v2 reservation covers 8 ÷ 16 = 50% of the larger VM's compute cost, and the remaining half is uncovered by that reservation. Running more VMs than the reserved quantity leaves usage uncovered the same way.
A reservation can be optimized for capacity priority instead of instance size flexibility, so confirm which setting was chosen before expecting coverage across sizes. For current ratios, use the API or PowerShell. Microsoft stopped updating the ratio CSV on May 9, 2026 and scheduled its removal for August 30, 2026. Multiplying usage quantity by RINormalizationRatio from AdditionalInfo converts it to the relative footprint.
Windows software and ineligible VM usage need separate checks
| Finding | How to confirm | Response |
|---|---|---|
| Windows software charge | Compute is discounted; software bills separately per virtual CPU | Check Azure Hybrid Benefit for software coverage |
| Ineligible VM usage | A-series, G-series, preview size or promotional meter; Spot has no reservations | Exclude this usage from reservation coverage planning |
| Overlapping reservations | Two reservations cover the same VM type in one subscription | Inspect allocation before adding quantity |
| Savings plan receives usage | Check reservation compatibility for that usage | Reservations apply first. If the savings plan took the hour, no available compatible reservation covered that VM-hour; check where the reserved hours went |
| Stopped VM | Compare billed compute with actual reservation usage | Do not infer coverage from the power-state label alone |
Microsoft's two pages use "stopped" differently. The charges page says stopped VMs remain billed and continue to use reserved hours, while the troubleshooting page says the benefit does not apply until the VM runs again. Billed compute settles which case applies: a matching VM that is still billed continues to use reserved hours, and when no matching resource is found in scope, the reserved hours are lost.
Resource details show which VM received the hours
Daily summaries locate the gap; resource details establish allocation. The reservation summary commands in the Azure command-line interface (CLI) are in preview.
This read-only command requests daily summaries for one reservation. Replace the placeholders with the reservation order ID and reservation ID, and keep both dates when supplying a daily start date.
az consumption reservation summary list \
--grain daily \
--reservation-order-id <ORDER_ID> \
--reservation-id <RES_ID> \
--start-date 2026-09-01 \
--end-date 2026-09-25 \
-o jsonRead the raw JSON before selecting fields, and check the output for the Summaries REST API names reservedHours, usedHours and avgUtilizationPercentage. Compare reserved with used hours only once usage reporting for those dates is complete.
For per-VM allocation, the Reservation Details API returns instanceId, instanceFlexibilityGroup, instanceFlexibilityRatio, reservedHours and usedHours, where instanceId is the resource name or the full resource ID. In cost details, look for PricingModel = Reservation with ChargeType = Usage, then use ReservationId, ReservationName and ProductOrderId for attribution. BenefitId and BenefitName identify savings plans instead.
Without billing access, ask the billing owner for the daily summaries and resource details covering the affected reservation and dates, plus the Amortized Cost UnusedReservation rows for the same period.
Rescope a boundary mismatch; exchange a lasting attribute change
For the example fleet, choose a scope that includes the three uncovered VMs within the enrollment. Rescoping is not a commercial transaction and leaves the term unchanged, which makes it the first response whenever the VMs already sit inside the billing context. For a change from shared to single scope, check that the person updating the scope owns the target subscription.
Exchange when sustained demand has moved to a different region or to a size outside the flexibility group, subject to exchange eligibility. A different size, series, region or payment frequency resets the term of the new reservation. If matching demand will return inside the current term, compare the reserved hours that will sit unused until then with the cost of restarting a term, and exchange only if the restart wins.
The exchange policy updated on July 29, 2026 gives reservations purchased before February 1, 2027 one final exchange. Reservations purchased after February 1, 2027 are not eligible for exchange where savings plans support the service. Instance size flexibility is unaffected by the change.
Check that the replacement is still sold before planning an exchange: since July 1, 2026, select VM series are no longer available for reservation purchase or renewal. Refunds cannot exceed USD 50,000 in a rolling 12-month window, and Microsoft is not currently charging early termination fees for reservation refunds.
When this does not apply
Skip this diagnosis if the only remaining charge is Windows software beside correctly discounted compute. VM reservations cover compute only and do not reserve or guarantee capacity.
Sources
CloudFinOpsPro guides are researched, written, independently reviewed and edited by an automated editorial pipeline, then checked against the official sources listed above. How we work.