Azure's cost tooling is genuinely good — Cost Management + Billing gives more granular visibility out of the box than most teams use. The gap is almost never visibility; it's that nobody wired the levers that actually change the bill. These are the ones that moved ours the most.

Reserved Instances vs. Savings Plans: pick based on flexibility need

Azure offers two overlapping discount mechanisms, and picking the wrong one leaves money on the table:

Mechanism Discount depth Flexibility Best for
Reserved Instances Up to ~72% (3-year) Locked to VM size + region, exchangeable with restrictions Stable, predictable workloads (databases, core services)
Azure Savings Plans Up to ~65% Applies across VM sizes/regions/families automatically Workloads that shift shape over time

The rule I use: if a workload's VM size hasn't changed in six months and isn't expected to, buy a Reserved Instance for the deeper discount. If the team is still actively right-sizing or the workload's shape changes with growth, a Savings Plan captures most of the discount without locking in a commitment that becomes wrong in four months.

az costmanagement reservation-recommendation list \
  --scope "/subscriptions/<sub-id>" \
  --resource-group-filter prod-rg

Run that recommendation report before buying anything — it's built from your actual usage history, not a guess.

Spot VMs: real savings, with eviction handled properly

Spot VMs run at up to 90% off on-demand pricing, with the catch that Azure can evict them with as little as 30 seconds' notice when it needs the capacity back. The workloads this fits are batch processing, CI build agents, and stateless horizontally-scaled services — never anything stateful without its own replication.

az vm create \
  --resource-group batch-rg \
  --name batch-worker \
  --priority Spot \
  --eviction-policy Delete \
  --max-price -1 \
  --image Ubuntu2204

--max-price -1 means "don't evict me purely for price, only for capacity" — the setting I use almost everywhere, since capacity-driven eviction is rare enough that price-based eviction adds risk without much additional savings.

Handle the eviction notice properly rather than letting the workload just die:

# Poll the scheduled events endpoint from inside the VM
curl -H Metadata:true \
  "http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01"

A response containing a Preempt event type means the VM has roughly 30 seconds. A batch job checkpointing its progress on receiving that signal loses minutes of work instead of hours.

Budgets that alert before the invoice, not after

The default mistake is checking Cost Management dashboards reactively, after a spend spike has already happened. Set budget alerts with multiple thresholds instead:

az consumption budget create \
  --budget-name monthly-prod-budget \
  --amount 5000 \
  --time-grain Monthly \
  --category Cost \
  --notifications '{
    "Actual_GreaterThan_80_Percent": {
      "enabled": true,
      "operator": "GreaterThan",
      "threshold": 80,
      "contactEmails": ["platform-team@company.com"]
    },
    "Forecasted_GreaterThan_100_Percent": {
      "enabled": true,
      "operator": "GreaterThan",
      "threshold": 100,
      "thresholdType": "Forecasted",
      "contactEmails": ["platform-team@company.com"]
    }
  }'

The Forecasted threshold is the one most teams skip and shouldn't — it fires based on projected month-end spend given the current trajectory, which means the team hears about a runaway cost 15 days before the bill, not on the 1st of next month when it's already too late to act.

The checklist I actually run monthly

  • Review the Reservation recommendation report — buying patterns shift as workloads mature
  • Audit for orphaned resources: unattached managed disks, idle public IPs, empty resource groups still accruing minor charges
  • Confirm Spot eviction handling is still wired up correctly after any recent deployment changes
  • Check Advisor's cost recommendations — Azure Advisor surfaces right-sizing suggestions from actual utilization data, updated continuously
  • Verify budget alert thresholds still match current spend baselines, not last year's

Where the actual savings come from

In practice, the sequence that moved the needle most was: right-size VMs against real utilization data (Advisor does this analysis automatically), move the now-correctly-sized steady-state workloads to Reservations or Savings Plans, and push anything interruption-tolerant onto Spot. Budget alerts don't save money directly — they're what stops the next six months of drift from becoming the next incident report.