The Hidden Cost of Commitment-Based Discounts Gone Wrong
Azure reservations and savings plans can slash your compute bill by up to 72 percent. That number gets printed in every Microsoft pricing page, repeated in every FinOps presentation, and cited in every cloud cost optimization article. What those sources mention less often is the flip side: a reservation that sits at 60 percent utilization is not saving you 72 percent — it might barely be breaking even against pay-as-you-go pricing.
Commitment-based discounts are a bet. You commit to a certain level of usage, and Azure gives you a discount in return. When your actual usage matches or exceeds that commitment, you win. When it falls short, you pay for capacity you never consumed. The discount is strictly use-it-or-lose-it — unused reserved hours in any given period vanish and cannot be carried forward.
This guide focuses on the practical mechanics of monitoring and optimizing that bet. You will learn how to measure utilization for both reservations and savings plans, identify underperforming commitments, and take corrective action before wasted spend accumulates into a material budget problem.
Reservations vs. Savings Plans: When Each Applies
Before diving into utilization analysis, it helps to understand what you are measuring and why the two commitment types behave differently.
Reservations lock you into a specific VM instance family (or other resource type) within a specific Azure region. You purchase a certain quantity of, say, D4s_v5 instances in East US, and the discount applies only when matching VMs are running in that region. The trade-off for this rigidity is maximum savings — reservations typically offer the deepest discounts.
Savings plans work differently. Instead of committing to a specific resource, you commit to a fixed hourly spend amount across all eligible compute services in any region. A $10/hour compute savings plan applies its discount wherever your compute spending occurs, whether that is virtual machines in East US, App Service plans in West Europe, or Azure Kubernetes Service nodes in Southeast Asia.
| Aspect | Reservations | Savings Plans |
|---|---|---|
| Commitment | Specific instance type + region | Fixed hourly dollar amount, any eligible compute |
| Flexibility | Limited to same VM series (with instance size flexibility) | Any eligible service, any region |
| Maximum Savings | Up to 72% | Up to 65% |
| Utilization Risk | Higher — tied to specific workloads | Lower — broadly applicable |
| Term | 1-year or 3-year | 1-year or 3-year |
Microsoft recommends a specific optimization sequence: right-size resources first, exchange underutilized reservations, trade in rigid reservations for savings plans where appropriate, then purchase new reservations for stable workloads and savings plans for everything else. Utilization analysis tells you exactly where you stand in that sequence.
Checking Utilization in the Azure Portal
The fastest path to understanding how well your commitments are performing lives in the Azure portal. Both reservations and savings plans surface utilization data through dedicated blades.
Reservation Utilization
Navigate to Reservations in the Azure portal (search for “Reservations” in the top search bar or go directly to the Reservations blade). The list view displays every reservation in your tenant with a utilization percentage column showing the last known value. Select any reservation’s utilization percentage to open a detailed utilization history chart.
The utilization chart shows daily utilization over the selected period, plotted as a percentage. A healthy reservation stays consistently above 95 percent. Anything below 80 percent deserves investigation, and anything below 50 percent is actively costing you money compared to pay-as-you-go.
For billing administrators on Enterprise Agreement or Microsoft Customer Agreement accounts, the path is slightly different: navigate to Cost Management + Billing, select your billing scope, then open Reservations from the left navigation.
Savings Plan Utilization
Search for “Savings plans” in the Azure portal to open the savings plan management blade. The list view shows last known utilization for the most recent day and the trailing seven-day average. Select a specific savings plan to view the full utilization history.
One important note: utilization data for newly purchased savings plans can take up to 48 hours to appear. If you just made a purchase and see zero utilization, wait before raising alarms.
The Amortized Cost Perspective
The standard utilization percentage tells you how much of your reserved capacity was consumed. The amortized cost view in Cost Analysis tells you the financial impact. Navigate to Cost Management → Cost analysis, switch the metric from Actual cost to Amortized cost, and filter for your reservations.
In amortized view, reservation purchases are spread across each day of the commitment term rather than appearing as a single large charge. More importantly, unused reservation hours appear as a distinct charge type called UnusedReservation, making it straightforward to quantify exactly how many dollars are being wasted. For savings plans, the equivalent charge type is UnusedSavingsPlan.
Key Utilization Metrics and What They Mean
When you pull utilization data — whether from the portal, REST API, or PowerShell — several metrics tell the full story beyond the headline percentage.
| Metric | What It Measures | Target |
|---|---|---|
| avgUtilizationPercentage | Average utilization across the time range | ≥ 95% |
| minUtilizationPercentage | Lowest hourly utilization in the period | Watch for consistent lows |
| maxUtilizationPercentage | Highest hourly utilization in the period | Should be at or near 100% |
| reservedHours | Total hours reserved (24 × quantity × days) | — |
| usedHours | Hours consumed against reservation | Close to reservedHours |
| Effective savings rate | (PayGPrice − Cost) / PayGPrice × 100 | Positive and growing |
The minimum utilization percentage is often more revealing than the average. A reservation that averages 92 percent but drops to 30 percent every weekend suggests a workload that does not run 24/7 — meaning a smaller reservation combined with pay-as-you-go for peak periods might actually be cheaper.
Querying Utilization Data Through the REST API
Programmatic access to utilization data enables automated monitoring, custom dashboards, and integration with ticketing systems that can trigger remediation workflows when utilization drops below thresholds.
Reservation Summaries
The Consumption API provides daily or monthly reservation utilization summaries:
GET https://management.azure.com/providers/Microsoft.Billing/billingAccounts/{billingAccountId}/providers/Microsoft.Consumption/reservationSummaries?api-version=2024-08-01&grain=daily&$filter=properties/usageDate ge 2026-03-01 AND properties/usageDate le 2026-03-31
The response includes avgUtilizationPercentage, minUtilizationPercentage, maxUtilizationPercentage, reservedHours, and usedHours for each reservation on each day. For monthly grain, omit the filter and set grain=monthly.
Benefit Utilization Summaries (Savings Plans and Reservations)
The Cost Management API provides a unified view across both commitment types:
GET https://management.azure.com/providers/Microsoft.Billing/billingAccounts/{billingAccountId}/providers/Microsoft.CostManagement/benefitUtilizationSummaries?api-version=2025-03-01&filter=properties/usageDate ge 2026-03-01 and properties/usageDate le 2026-03-31&grainParameter=Daily
This endpoint returns utilization for savings plans and reservations together, with a benefitType field that distinguishes between SavingsPlan, Reservation, and IncludedQuantity. The grainParameter accepts Hourly, Daily, or Monthly — hourly data is particularly useful for identifying specific time windows when utilization drops.
Detailed Reservation Usage
When you need to understand which specific resources consumed reservation capacity:
GET https://management.azure.com/providers/Microsoft.Billing/billingAccounts/{billingAccountId}/providers/Microsoft.Consumption/reservationDetails?api-version=2024-08-01&$filter=properties/usageDate ge 2026-03-01 AND properties/usageDate le 2026-03-07
This returns per-instance, per-day records showing exactly which VM (by instanceId) consumed hours against the reservation. Be cautious with large date ranges — the ARM payload limit is 12 MB, so narrow the time window or use the asynchronous Generate Reservation Details Report API for bulk exports.
PowerShell Automation for Utilization Monitoring
The Az.Reservations module provides cmdlets focused on reservation management, while utilization data typically comes through the Consumption API.
Listing All Reservations and Their Status
# List all reservations in the tenant
$reservations = Get-AzReservation
# Display key information
$reservations | Select-Object @{N='OrderId';E={$_.ReservationOrderId}},
@{N='Name';E={$_.DisplayName}},
@{N='SKU';E={$_.Sku}},
@{N='State';E={$_.ProvisioningState}},
@{N='ExpiryDate';E={$_.ExpiryDateTime}} |
Format-Table -AutoSize
Querying Utilization via REST in PowerShell
# Get daily utilization summaries for current billing period
$token = (Get-AzAccessToken -ResourceUrl https://management.azure.com).Token
$billingAccountId = "your-billing-account-id"
$startDate = (Get-Date).AddDays(-30).ToString("yyyy-MM-dd")
$endDate = (Get-Date).ToString("yyyy-MM-dd")
$uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/$billingAccountId/providers/Microsoft.Consumption/reservationSummaries?api-version=2024-08-01&grain=daily&`$filter=properties/usageDate ge $startDate AND properties/usageDate le $endDate"
$headers = @{ Authorization = "Bearer $token" }
$response = Invoke-RestMethod -Uri $uri -Headers $headers -Method GET
# Find underutilized reservations (below 80%)
$response.value | Where-Object {
$_.properties.avgUtilizationPercentage -lt 80
} | Select-Object @{N='Date';E={$_.properties.usageDate}},
@{N='ReservationId';E={$_.properties.reservationId}},
@{N='Utilization';E={[math]::Round($_.properties.avgUtilizationPercentage,1)}},
@{N='UsedHours';E={$_.properties.usedHours}},
@{N='ReservedHours';E={$_.properties.reservedHours}} |
Format-Table -AutoSize
This script outputs every day where any reservation fell below 80 percent utilization, making it easy to spot patterns like weekend dips or specific reservations that consistently underperform.
Setting Up Utilization Alerts
Reactive monitoring through manual checks does not scale. Azure Cost Management supports utilization alerts that notify you automatically when reservations drop below a defined threshold.
Navigate to Cost Management + Billing, select your billing scope, open Cost Management → Cost alerts, and click Add. Set the alert type to Reservation utilization, configure the threshold percentage (95 percent is a good starting point), choose the time grain (Last 7-days or Last 30-days), and specify the notification frequency (daily or weekly).
The alert emails include the top five underutilized reservations, their utilization percentages, and a direct link to the portal for investigation. You can add up to 20 email recipients per alert rule.
One limitation to be aware of: prepurchase plans for Azure Databricks, Microsoft Defender for Cloud, and Synapse Pre-Purchase are not supported by utilization alerts. Monitor these through the portal or REST API instead.
Identifying and Fixing Underutilized Commitments
Finding underutilized reservations is straightforward. The harder part is deciding what to do about them. Microsoft provides several remediation paths, each suited to different root causes.
Match Resources to Reservations
The most common cause of low utilization is a mismatch between the reserved instance size and what is actually deployed. If you purchased a reservation for D8s_v5 instances but your team deployed D4s_v5 instead, the reservation may not apply unless instance size flexibility is enabled. Verify that the deployed VM sizes fall within the same flexibility group as the reserved size.
Enable Instance Size Flexibility
When a reservation has Shared scope, instance size flexibility is automatically applied. This means a D8s_v5 reservation can cover two D4s_v5 instances or four D2s_v5 instances within the same VM series. If your reservation is scoped to a single subscription or resource group, consider broadening the scope to maximize the chances of matching available resources.
Exchange for a Better Fit
Azure allows self-service exchanges on most reservation types. If your workload changed — you moved from D-series to E-series VMs, or shifted to a different region — you can exchange the existing reservation for one that matches your current infrastructure. The exchange preserves the remaining monetary value of the original commitment.
Trade In for a Savings Plan
When a reservation consistently underperforms because your workloads are dynamic or spread across multiple regions and VM families, trading it in for a compute savings plan often makes more sense. You lose a few percentage points of maximum discount, but the savings plan inherent flexibility means it will actually be used at near-100 percent utilization.
Azure Advisor Recommendations
Azure Advisor actively monitors your reservation portfolio and generates cost recommendations when it detects issues. Common recommendations include configuring automatic renewal for expiring reservations, purchasing savings plans for workloads that do not fit the reservation model well, and buying new reservations for services with stable usage patterns. All reservation-related Advisor recommendations are classified as High impact.
Access these through Azure Portal → Advisor → Cost tab. Advisor recommendations cover VMs, SQL Database, Cosmos DB, Azure Files, Managed Disks, Blob Storage, Redis Cache, Data Explorer, App Service, and several other services.
Calculating Real Savings from Commitment Discounts
Utilization percentage alone does not tell you whether your commitments are generating meaningful savings. You need to calculate the effective savings rate, which accounts for both the discount received on used capacity and the waste from unused capacity.
The formula is straightforward when working with amortized cost data:
- Pull amortized cost records filtered for
PricingModel = ReservationorPricingModel = SavingsPlan - Calculate on-demand equivalent: sum of
UnitPrice × Quantityacross all records - Calculate actual commitment cost: sum of
Cost(which includes both used and unused amounts in amortized view) - Effective savings = (On-demand equivalent − Actual cost) / On-demand equivalent × 100
A reservation with 90 percent utilization and a 40 percent discount rate actually delivers about 36 percent effective savings after accounting for the 10 percent waste. Compare this against a savings plan with 99 percent utilization and a 35 percent discount rate, which delivers roughly 34.6 percent effective savings. The reservation still wins by a thin margin in this example — but if utilization drops to 80 percent, the effective savings fall to 32 percent, and the savings plan becomes the better deal.
Building a Sustainable Commitment Monitoring Practice
Analyzing utilization once and fixing problems is a start. Building a sustainable practice means establishing habits and automation that prevent utilization problems from recurring.
Review Before Renewal
Every reservation has an expiry date. Set calendar reminders 90 days before each expiry to review utilization trends over the reservation’s life. If utilization averaged above 95 percent, renew with confidence. If it wavered between 70 and 90 percent, consider switching to a savings plan or reducing the quantity. If it regularly fell below 70 percent, the workload may have fundamental changes that make commitment-based pricing the wrong model.
Right-Size Before You Commit
The optimization sequence matters: right-size your resources before purchasing or renewing commitments. A reservation sized for D16s_v5 instances makes no sense if your workload actually needs D8s_v5. Check Azure Advisor’s right-sizing recommendations and adjust VM sizes before evaluating reservation purchases.
Separate Stable from Variable Workloads
Cover your baseline load — the minimum compute that runs 24/7, 365 days a year — with reservations for maximum savings. Cover the variable layer above that baseline with savings plans for flexibility. Leave burst capacity on pay-as-you-go. This layered approach maximizes total savings while keeping utilization high across all commitment tiers.
Automate the Reporting
Schedule the PowerShell scripts from this guide to run weekly, output utilization summaries to a shared Teams channel or email distribution list, and flag anything below your organizational threshold. When underutilization becomes visible to the people who manage the workloads, they fix it. When it stays buried in a billing portal that only the finance team checks monthly, it persists for the entire reservation term.
Commitment-based discounts remain one of the most effective levers for reducing Azure costs. The key is treating them not as a purchase-and-forget decision, but as an ongoing relationship between your workload patterns and your financial commitments — one that deserves regular attention, honest measurement, and timely adjustment when the numbers stop adding up.
For more details, refer to the official documentation: What is Microsoft Cost Management.