Azure Governance

Azure Commitment Strategy: Reservations, Savings Plans, and Hybrid Benefit Optimization

Commitment discounts are the single largest lever in an Azure bill, and the one teams most often pull wrong. The failure mode is not “we forgot to buy reservations” — it is buying the wrong instrument, at the wrong scope, for a baseline that drifts, and then discovering at renewal that half the commitment went unused while pay-as-you-go (PAYG) charges piled up next to it. Every dollar of unused commitment is a negative discount: you paid up front and got nothing.

This guide is the decision logic, not a feature tour. We pick the right instrument per workload, size it from real utilization data, choose scope deliberately, stack Azure Hybrid Benefit (AHB) on top, and build the exchange-and-review cadence that keeps the portfolio matched to a moving estate. Numbers here are illustrative; pull live rates from the Azure pricing calculator and your EA/MCA price sheet before committing.

Mental model. Reservations and savings plans discount compute and a few other resource types. AHB discounts licensing (Windows Server, SQL Server) and is independent — it stacks. PAYG is your liquidity reserve for the part of the baseline you are not yet confident is permanent. Most mature estates run all three at once.

1. PAYG vs reservations vs savings plans: where each wins

The three instruments trade discount depth against flexibility. That is the entire decision.

Instrument Typical discount Locks you to Best for
Pay-as-you-go 0% (baseline) nothing spiky, short-lived, or uncertain workloads
Compute savings plan moderate an hourly $ spend, 1 or 3 yr compute that moves across SKU/region/OS
Reservation deepest a specific SKU + region (or instance-size-flexible group) stable, long-lived, predictable footprint

The hierarchy is simple: reservations are the deepest discount but the least flexible; savings plans are shallower but flex across SKU family, region, and OS; PAYG is full price but free to walk away. Azure’s billing engine applies the deepest applicable discount first each hour. The official guidance — and the right default — is that a reservation, when it fits, beats a savings plan on price for the same usage. Savings plans win when the shape of usage is uncertain even though the spend is stable.

Decision flow for any compute baseline:

  1. Is this footprint stable in SKU and region for 1+ year? -> Reservation (instance-size-flexible where the family supports it).
  2. Stable in spend but likely to change SKU/region/OS (autoscaling fleets, migrations, AKS node pool churn)? -> Compute savings plan.
  3. Neither stable nor predictable? -> Leave on PAYG and revisit next cycle.

A nuance that trips people: the compute savings plan covers a broad set of compute services (VMs, dedicated hosts, App Service, Container Instances, Azure Functions Premium, and more) under one hourly-dollar commitment, automatically applying to the highest-PAYG-rate eligible usage first. Reservations are per-resource-type — a VM reservation does not pay down an App Service plan. That breadth is exactly why savings plans absorb migration churn that would strand a reservation.

What savings plans do not cover is just as important: storage, networking/egress, databases priced by DTU/vCore reservation (those have their own reservation products), Spot, and anything already on PAYG-only meters. Do not assume a savings plan blankets the bill.

2. Reading utilization and coverage to size commitments correctly

Never size a commitment off a single month or a portal eyeball. You need two numbers per workload, tracked over time:

Size to the stable floor of the last 30-60 days, not the average and never the peak. The classic mistake is committing to the mean, which guarantees you under-utilize during the troughs.

Pull the raw signal from amortized cost data via Cost Management. The amortized view spreads an upfront reservation purchase across its term so a day’s true run-rate is visible instead of a lump on purchase day.

# Export amortized usage so reservation/savings-plan cost is spread across the term,
# not booked as a lump on the purchase date.
az costmanagement export create \
  --name amortized-daily \
  --type AmortizedCost \
  --scope "subscriptions/<sub-id>" \
  --storage-account-id "<storage-resource-id>" \
  --storage-container "cost-exports" \
  --storage-directory "amortized" \
  --timeframe MonthToDate \
  --recurrence Daily \
  --recurrence-period from="2026-06-01T00:00:00Z" to="2026-12-31T00:00:00Z"

Then query the exported data (or the same fields in a Log Analytics / cost workspace) to find the stable hourly floor per SKU. The shape that matters is the minimum sustained concurrency, which is your safe reservation quantity:

// Stable VM concurrency floor per SKU over 60 days.
// The 5th-percentile hourly running count is a defensible reservation quantity:
// you run at least this many essentially all the time.
Usage
| where TimeGenerated > ago(60d)
| where MeterCategory == "Virtual Machines"
| summarize RunningVMs = dcount(ResourceId) by SkuName, bin(TimeGenerated, 1h)
| summarize FloorQty = percentile(RunningVMs, 5),
            MedianQty = percentile(RunningVMs, 50),
            PeakQty   = max(RunningVMs)
  by SkuName
| order by FloorQty desc

Commit the FloorQty to reservations, cover the band between floor and median with a savings plan, and let the peak ride on PAYG. That layering is the whole strategy in one query.

For savings-plan sizing specifically, Azure’s own recommendation engine is worth consulting — Cost Management surfaces a recommended hourly commitment at 1-yr and 3-yr terms based on your last 7/30/60 days of eligible usage, with a projected utilization. Treat it as a starting point, then haircut it 5-10% toward the conservative side because the recommendation assumes your recent past repeats exactly.

3. Reservation scope: shared, single-subscription, and management-group

Scope decides which usage a reservation is allowed to pay down. Get it wrong and a perfectly-sized reservation sits idle next to PAYG usage it was never permitted to touch.

Scope A reservation here applies to Use when
Single subscription matching usage in one subscription only one team owns and funds the workload; strict isolation
Single resource group matching usage in one RG even tighter chargeback boundary
Shared matching usage across all subscriptions in the billing context maximize utilization; central platform team owns commitments
Management group matching usage across subscriptions under that MG shared, but bounded to an org unit

The default and usually correct choice for a platform team is shared (or management-group scope when you want a boundary): it lets one reservation float to wherever the matching SKU is running, which maximizes utilization — the number that actually determines ROI. Pin to single-subscription only when a business unit funds its own commitment and must not subsidize another, or when chargeback rules forbid cross-charging.

The operationally valuable fact: scope is mutable after purchase, at no cost. If a shared reservation is under-utilizing because the workload it was bought for shrank, narrow or re-point its scope to where the matching usage actually lives — no exchange, no refund, just a property change.

# List reservations and their current utilization so you can spot misallocation.
az reservations reservation-order list -o table

# Re-point a reservation to a management group (or flip to Shared) to chase usage.
az reservations reservation update \
  --reservation-order-id "<order-id>" \
  --reservation-id "<reservation-id>" \
  --applied-scope-type ManagementGroup \
  --applied-scope-groups "/providers/Microsoft.Management/managementGroups/landing-zones"

Governance gotcha. A shared reservation can be consumed by any subscription in the billing scope, which can quietly cross-subsidize teams and muddy showback. If your chargeback model is strict, prefer management-group scope so the discount stays inside an org boundary, and reconcile with amortized cost so each team sees its effective (post-discount) rate, not the list price.

4. Compute savings plans for flexible, cross-SKU and cross-region coverage

A compute savings plan is a commitment to spend a fixed dollars-per-hour on eligible compute for 1 or 3 years, in exchange for savings-plan rates on usage up to that hourly amount. Usage above the commitment bills at PAYG; usage below means you paid for hours you did not consume — the same under-utilization trap as a reservation, just denominated in dollars.

Why platform teams reach for it over reservations:

That last point is the key behavioral difference from reservations: you do not assign a savings plan to a resource. The billing engine sweeps each hour and discounts the most expensive eligible usage until your hourly commitment is exhausted. You buy flexibility, and you pay for it with a slightly shallower discount than the equivalent reservation.

# Inspect savings-plan recommendations (hourly commitment + projected utilization)
# before you buy. Look-back of 30 days, 3-year term, shared scope.
az billing-benefits savings-plan-order list -o table

Practical rule: layer savings plans under reservations, not instead of them. Reservations cover the immovable floor at the deepest discount; the savings plan covers the flexible band above it at a still-meaningful discount; PAYG handles the spiky top. Buying only savings plans because they are “easier” leaves the deepest reservation discount on the table for the part of the estate that genuinely never moves.

5. Azure Hybrid Benefit for Windows Server and SQL licensing

AHB is a licensing discount, orthogonal to compute commitments. If you own Windows Server or SQL Server licenses with active Software Assurance (or qualifying subscription licenses), AHB lets you bring them to Azure and stop paying the license portion of the meter — you pay the base compute rate only. For Windows Server VMs the savings are substantial; for SQL the savings can be larger still because SQL licensing is expensive.

Core entitlements to know:

Enabling AHB is a property, not a purchase — flip it on existing resources:

# Windows Server VM: switch the license type to bring your own Windows license.
az vm update -g rg-prod -n vm-app-01 --license-type Windows_Server

# Convert back to pay-as-you-go licensing (e.g., if you run out of entitlements).
az vm update -g rg-prod -n vm-app-01 --license-type None

For SQL on Azure VMs you set the license type on the SQL virtual machine resource (the IaaS extension), not the VM:

# SQL Server IaaS: AHB / bring-your-own-license at the SQL VM resource level.
az sql vm update -g rg-prod -n vm-sql-01 --license-type AHUB

Azure SQL Database and Managed Instance expose AHB as a property of the database/instance:

# Azure SQL Database: enable Azure Hybrid Benefit (base-rate licensing).
az sql db update -g rg-prod -s sql-logical-01 -n salesdb --license-type BasePrice

In Bicep, make AHB the default for managed compute so nobody forgets it at deploy time:

resource sqlMi 'Microsoft.Sql/managedInstances@2023-08-01-preview' = {
  name: 'mi-prod-01'
  location: location
  sku: { name: 'GP_Gen8', tier: 'GeneralPurpose' }
  properties: {
    // BasePrice = Azure Hybrid Benefit; LicenseIncluded = pay for the license.
    licenseType: 'BasePrice'
    vCores: 8
    storageSizeInGB: 256
    subnetId: subnetId
  }
}

Compliance is on you. Azure does not verify you actually hold the licenses you claim. AHB is an entitlement you assert; a license audit can claw it back. Track AHB usage against owned SA seats in a spreadsheet or your SAM tool, and gate the property behind policy so it is a deliberate, attributable choice — not a default someone flipped to cut their bill.

6. Stacking AHB with reservations and dev/test pricing

The discounts compose, and the savings multiply because they hit different parts of the meter:

For non-production there is a fourth lever: an Enterprise Dev/Test or Pay-As-You-Go Dev/Test subscription removes the Windows/SQL license charge entirely for Visual Studio subscribers’ dev/test workloads, with no SA required. You generally would not apply AHB there — the dev/test subscription already zeroes the license. The discount layering therefore differs by environment:

Environment Compute discount License treatment
Production reservation / savings plan AHB (bring SA licenses)
Dev/Test reservation / savings plan (dev/test rates) covered by Dev/Test subscription; AHB not needed

The trap is applying AHB to a dev/test subscription and assuming it stacks — it does not double-discount the license, and you have now consumed an SA entitlement that a production VM could have used. Reserve AHB entitlements for production, where they are the only way to drop the license charge.

7. Exchanges, refunds, and avoiding underutilized commitments

Estates drift. The instrument that fit at purchase will not fit forever, so you must know the exit mechanics before you buy.

Reservations.

Savings plans.

The practical implication ties the whole strategy together:

Because VM reservation exchanges are gone and savings plans cannot be canceled, conservatism at purchase is the entire game. Buy reservations only for the part of the floor you are certain is permanent. Cover everything merely “probable” with a savings plan sized below your true floor. Let the rest ride PAYG. Under-committing costs you a little discount; over-committing costs you cash you cannot get back.

Catch under-utilization early with a recurring report. Reservation utilization below 100% over a trailing window is the first signal to re-scope (cheap) before considering a refund (expensive, capped):

# Trailing reservation utilization. Anything under ~95% is a re-scope candidate.
az consumption reservation summary list \
  --grain daily \
  --start-date 2026-05-01 \
  --end-date 2026-05-31 \
  -o table

Enterprise scenario

A platform team running a regulated insurance workload had a stable production fleet of roughly 120 D8s_v5 VMs in westeurope and bought 3-year VM reservations against it at shared scope. Six months in, the application team kicked off a migration to E-series memory-optimized VMs (heavier in-memory rating engine) and, for a new data-residency requirement, stood up a second region in northeurope. Reservation utilization on the D8s_v5 order cratered to ~55% almost overnight: the E-series and northeurope usage billed at full PAYG while the paid-for D8s_v5 reservation sat idle. The instinct was to exchange the reservations into E-series — but those reservations were purchased after the compute-exchange cutoff, so like-for-like VM exchange was unavailable, and a refund was both capped and wasteful.

The constraint, then: a deep but now-mismatched 3-year reservation that could not be exchanged, against a fleet that had become flexible by nature (active migration, multi-region, changing SKU family).

The fix was to stop fighting the reservation model and let it expire gracefully on the residual D8s_v5 footprint while moving the flexible portion of the estate onto a compute savings plan, which is SKU- and region-agnostic by design and therefore immune to exactly this churn. They sized the savings plan from the 5th-percentile hourly spend across both regions and both SKU families combined — not per-SKU — so the commitment floated to wherever usage landed.

// Cross-SKU, cross-region hourly spend floor that a savings plan can safely commit to.
// Summing eligible compute spend (not per-SKU) is what makes the commitment
// resilient to the D->E migration and the new region.
Usage
| where TimeGenerated > ago(60d)
| where MeterCategory in ("Virtual Machines")
| where ResourceLocation in ("westeurope", "northeurope")
| summarize HourlySpend = sum(PreTaxCost) by bin(TimeGenerated, 1h)
| summarize CommitFloorPerHour = percentile(HourlySpend, 5)

They committed ~80% of that floor as a 1-year savings plan (short term, because the migration meant the future shape was still moving), kept AHB enabled across both SKU families and regions to hold the Windows license savings constant through the migration, and let the old D8s_v5 reservations amortize out. Blended effective discount recovered to within a couple of points of the original target within one billing cycle, with zero stranded commitment going forward. The lesson the team wrote into their standards: reserve only the immovable floor; everything that can migrate goes on a savings plan.

Verify

Confirm the portfolio is actually working, not just purchased:

# 1. Reservation utilization should sit at ~100% across the trailing month.
az consumption reservation summary list --grain monthly \
  --start-date 2026-05-01 --end-date 2026-05-31 -o table

# 2. Savings-plan utilization (via cost exports / Cost Management) should be high;
#    persistent unused commitment means you over-sized the hourly dollar amount.
az billing-benefits savings-plan-order list -o table

# 3. AHB is actually applied where you think. Windows VMs should report a license type.
az vm list --query "[?licenseType=='Windows_Server'].{name:name, rg:resourceGroup}" -o table

# 4. SQL VMs carry AHUB where licensed.
az sql vm list --query "[].{name:name, license:sqlServerLicenseType}" -o table

Then reconcile against amortized cost in Cost Management: effective per-team rates should be visibly below list price, and your coverage percentage on stable workloads should be high. If utilization is high and coverage is high and amortized rates beat PAYG, the strategy is landing.

Commitment-review cadence checklist

Run this on a fixed monthly cadence with finance and the platform team in the room. Commitments are not fire-and-forget — they decay against a moving estate.

finopsreservationssavings-planshybrid-benefitcost

Comments

Keep Reading