Skip to main content
emnode
Cost

Renew expiring reservations before they lapse

One capability across every reservation in the estate: make sure no committed discount silently expires and reverts the workload behind it to on-demand rates, unless you genuinely mean to let it go.

13 min·10 sections·AZURE

Last reviewed

Renewing expiring reservations: the basics

What actually happens when an Azure reservation lapses?

A reservation is a one or three year commitment that buys a deep discount on a known quantity of compute, database or other capacity. When it expires, nothing breaks: the underlying virtual machines, SQL databases and other resources keep running exactly as before. What changes is the price. The discount stops, and every resource that was being matched against that reservation quietly reverts to pay-as-you-go on-demand rates from the moment of expiry. The workload looks identical on the resource blade, but the bill behind it has stepped up, often by a large fraction, with no alert and no outage to make anyone look.

Azure Advisor turns this into a specific cost recommendation: 'Configure automatic renewal for the expiring reservations', against the microsoft.capacity/reservationorders/reservations resource type. It surfaces reservations that are expiring soon or have recently expired, and it exists precisely because the failure mode is invisible. There is no error, no degraded service, just a higher invoice that shows up after the fact. Each expiring reservation is its own line on the recommendation, which is why an estate that bought a wave of reservations together can see a cluster of them come due at once.

The renewal setting is on by default at purchase, but it can be turned off, and reservations bought before a team standardised on auto-renew, or bought through a channel that defaulted it off, are the ones that lapse. The work is to find every reservation approaching expiry, decide which commitments you still want, set those to renew automatically (optionally re-pricing the renewal to current quantity and term), and let the ones you have genuinely outgrown expire on purpose rather than by accident.

In this lesson you will learn how an Azure reservation expires, why the lapse is invisible until the invoice, how to find every reservation approaching its expiry date across the estate, and how to set the ones worth keeping to renew automatically without overcommitting to capacity you no longer need. The links at the end go to the Microsoft guidance for the exact settings and commands.

Fun fact

The discount that expired on a quiet Tuesday

The most expensive thing about an expired reservation is how undramatic it is. There is no failed deployment, no paged engineer, no red banner. The virtual machines keep humming, the database keeps answering queries, and the only signal is a billing line that has quietly stepped up to on-demand. Teams routinely discover a lapsed reservation weeks later, in the monthly cost review, after paying the full undiscounted rate the whole time. Microsoft turned the renewal setting on by default at purchase precisely because this silent failure mode was costing customers real money, and Advisor still flags the reservations bought before that default, or with renewal switched off, so they do not slip through.

Finding expiring reservations across an estate

Priya runs the platform team at a company whose first big wave of reservations, bought together three years ago to cover a production migration, is all coming due in the same quarter. Azure Advisor is showing the expiring-reservation recommendation against several of them.

Rather than wait for the cost review to reveal the damage, Priya starts by listing which reservations are approaching expiry and which already have auto-renew switched off, so the commitments worth keeping can be separated from the ones the business has genuinely outgrown before anything lapses.

Start by listing the reservation items in an order with their expiry date and whether renewal is on. These are the commitments about to step back up to on-demand.

$ az reservations reservation list --reservation-order-id <orderId> --query "[].{name:properties.displayName, expires:properties.expiryDateTime, renew:properties.renew}" -o table
Name Expires Renew
--------------------------- -------------------- -------
prod-vm-d8sv5-3yr 2026-07-04T00:00:00Z False
sql-vcore-prod-3yr 2026-07-04T00:00:00Z True
# prod-vm-d8sv5-3yr expires in weeks with renew OFF: it will revert to on-demand. Fix it first.

A reservation that expires soon with renew set to False is the highest-value target: it will silently step its workload up to on-demand the moment it lapses.

How Azure decides a reservation is expiring, and what happens at expirydeep dive

Every reservation item carries an 'expiryDateTime' and a 'renew' boolean on its properties, under the microsoft.capacity/reservationorders/reservations resource. Advisor reads these to raise the recommendation when a reservation is close to, or just past, its expiry date. The renew flag is the single switch that decides what happens next: when it is true, Azure automatically purchases a replacement reservation at the expiry moment; when it is false, the reservation simply ends.

Crucially, renewal does not extend the existing reservation. It creates a brand new reservation that takes effect when the old one expires, so the discount is continuous as long as renew is true. By default the replacement matches the original quantity and term, but the renewal can be re-priced: you can set the renewal to a different term or quantity so the new commitment reflects what the workload actually needs now rather than what it needed three years ago. The renewal setting can be changed any time up to 48 hours before the expiry date.

When a reservation lapses with renew false, there is no control-plane event on the resources themselves. The compute, database or other capacity keeps running untouched. The only change is in billing: from the expiry timestamp, usage that was being matched against the reservation is charged at on-demand rates instead. That is what makes the lapse invisible until the invoice, and it is why setting renew to true ahead of time, rather than reacting after expiry, is the whole point of the recommendation.

What is the impact of letting a reservation lapse by accident?

The direct impact is straight cost leakage. From the expiry timestamp, every resource that was being discounted by the reservation is billed at on-demand rates, which is exactly the higher pricing the reservation was purchased to avoid. Because the workload keeps running normally, nothing surfaces the change except the bill, so the gap is often paid for weeks before anyone connects the rising cost to a lapsed commitment. For a reservation covering a fleet of production virtual machines or a SQL deployment, that gap is the difference between the committed rate and full pay-as-you-go, charged every hour.

The second-order impact is the scramble to recover. Once a lapse is spotted, the fix is to buy a replacement reservation, but a new purchase starts a fresh one or three year term from that day and does not refund the on-demand period already paid. Auto-renew avoids this entirely by creating the replacement at the moment of expiry, so the discount never stops. Reacting after the fact is always more expensive than renewing ahead of time.

On the forecasting side, an unrenewed reservation also distorts planning. A cost model built on the assumption that a workload is reserved will understate the run rate the moment the reservation lapses, so budgets and unit-economics figures drift from reality until the commitment is restored. Keeping reservations renewed for the workloads that are staying keeps the forecast honest as well as the bill low.

How do you protect the savings before reservations expire?

Work the recommendation as one renew-or-retire loop rather than reacting to each lapse. The order matters: decide which workloads are staying before you set anything to renew, so you do not auto-commit to capacity you are about to retire.

1. Inventory every reservation by expiry and renewal state

List each reservation with its expiry date and whether renew is on. Treat this inventory as the source of truth and sort by how soon each expires, because the closest to expiry with renew off is the one about to start leaking to on-demand.

2. Separate keep-forever workloads from genuine retirements

For each reservation, decide whether the workload behind it is still running and still wanted past the expiry date. Production capacity that is staying for years is an obvious renewal. A service being decommissioned or migrated off Azure is a deliberate lapse, and a workload that has shrunk is a renewal at reduced quantity.

3. Set the keepers to renew, highest value first

Turn on automatic renewal for every reservation covering a workload you are keeping, prioritising the largest commitments and those closest to expiry. Where the workload has changed, re-price the renewal to the current term and quantity so the new commitment matches today's need rather than a three-year-old estimate. The change is a single command per reservation and can be made up to 48 hours before expiry.

4. Make auto-renew the default and review on a cadence

Set renewal on at the point of every new purchase so future reservations never depend on someone remembering. Pair that with a recurring review of reservations approaching expiry, so the deliberate retirements are confirmed on purpose and nothing lapses by oversight.

# Protect the savings: turn on automatic renewal for the reservations you are keeping.
# Find the order ids first, then enable renew per reservation item.
for order in $(az reservations reservation-order list \
    --query "[].name" -o tsv); do
  for rid in $(az reservations reservation list \
      --reservation-order-id "$order" \
      --query "[?properties.renew==\`false\`].name" -o tsv); do
    az reservations reservation update \
      --reservation-order-id "$order" \
      --reservation-id "$rid" \
      --renew true
    echo "$order/$rid: automatic renewal enabled"
  done
done

# Or declare renewal in Bicep so new reservation orders renew by default:
#   resource res 'Microsoft.Capacity/reservationOrders@2022-11-01' = {
#     name: orderName
#     properties: {
#       displayName: 'prod-vm-d8sv5-3yr'
#       renew: true
#       term: 'P3Y'
#       quantity: 10
#     }
#   }

Quick quiz

Question 1 of 5

An Azure reservation covering a fleet of production virtual machines expires with auto-renew off. What actually happens to those VMs and their cost?

You can now treat expiring reservations as one capability rather than a scatter of calendar reminders: inventory every commitment by expiry date and renewal state, separate the keep-forever workloads from genuine retirements, set the keepers to renew automatically (re-pricing where the workload has changed), and make auto-renew the default for every new purchase. The links above go to the Microsoft guidance for the exact settings.

Back to the library