Back to Blog
FinOps
7 min read

Azure Won't Show You Spot Eviction History. So I Recorded 50 Days of It.

AzureSpot VMsFinOpsCost OptimisationVirtual Machines

You can rent a real Linux VM on Azure for $3.65 a month. That is a Standard_A1_v2 in Australia Central, 90% off on Spot. The biggest discount I have found is a confidential-compute VM in Central US at 91.6% off, $0.08 an hour instead of $0.95. Same hardware as on-demand, a fraction of the price.

The catch is the one everyone repeats: Azure can evict a spot VM with at least 30 seconds notice when it wants the capacity back. So the number that decides whether spot is safe for your workload is not the price. It is the eviction rate, the chance your box gets pulled.

I went to pull that number for every VM size in every region, for a free spot pricing tool I have been building. That turned into a much bigger project than I expected, because of two things Azure does with this data: it only ever shows you today's value, and it hides the fuller dataset behind a door you cannot open.

This is the follow-up to The Hidden Complexity of Azure Spot VM Pricing Data, where I covered why prices are easy and eviction rates are not.

The easy half: spot prices

Current spot prices come from the Azure Retail Prices API (https://prices.azure.com/api/retail/prices). No authentication, no subscription, no key. Filter for serviceName eq 'Virtual Machines' and a meterName containing Spot, page through it, and you have live pricing across every region and SKU. Genuinely simple.

The number that matters: eviction rate

Eviction rates are not in that API. The only documented public source is Azure Resource Graph, in the SpotResources table:

SpotResources
| where type =~ 'microsoft.compute/skuspotevictionrate/location'
| project skuName = tostring(sku.name), location, evictionRate = tostring(properties.evictionRate)

This needs Azure AD auth and a Reader role, and it must run at tenant scope. The SpotResources table does not work when you scope it to a subscription, so you deliberately leave the subscriptions array out. The rate comes back as a band, not a number: 0-5, 5-10, 10-15, 15-20, or 20+. Those are the same bands the portal shows.

And that is the whole story Azure gives you: one band, right now. No history, no trend, no sense of whether that 0-5% has been stable for months or dropped from 20%+ last week. For a workload you are about to commit real money to, that is the most important thing to know, and it is exactly what is missing.

So I started recording it

Azure does not keep the history, so I do. Every day, the tool snapshots the eviction band for all 26,344 SKU and region combinations I track and stores it. Fifty days in, the picture that a single point-in-time check completely hides is obvious:

  • Eviction bands move constantly. Of the 26,344 combinations, 9,751 have shifted to a higher risk band and 5,653 to a lower one over the recording window. The 0-5% you checked last month is not guaranteed to be 0-5% today.
  • GPU is the worst offender. NC-series GPU VMs sit in the high-risk bands more than any other family, by a wide margin. If you are training on spot, this is the family to watch.
  • Geography is stable and exploitable. The calmest regions right now are Australia, Poland and South Africa, all holding at 0-5%. If your workload is location-flexible, region choice is a lever.

The clearest way to see it is a single VM over time. Here is a Standard_E2ps_v5 in Central India: spot at $0.0120 an hour against $0.0650 on-demand, an 81.5% saving. Its eviction band over the recorded period stepped down from 20%+ all the way to 0-5%. A snapshot taken in week one would have told you to avoid it. A snapshot today says it is one of the safest bets on the platform. Only the history tells you it is improving.

As far as I can tell, this is data nobody else publishes, because Azure does not expose it and you have to record it yourself, day after day, to have it at all.

The buried half: a fuller dataset you cannot reach

While building this I hit a second wall. The public SpotResources table does not cover every VM. Take Standard_L96as_v4 in West US 2: Resource Graph returns no eviction band for it at all. But open the portal, start to build that exact VM in that exact region, and it shows 0-5%. Same box, same region, a blank from the API and a real band from the portal.

The portal is not reading Resource Graph. According to a captured trace shared in a Microsoft Q&A thread, it calls an internal, subscription-scoped endpoint, spotEvictionRates/history/bulkQuery, that only Microsoft's own portal clients are allowed to call. Customer credentials are rejected outright with OperationNotAllowed. I could not independently re-verify the exact endpoint in 2026, so treat the specifics as indicative. What is certain is the behaviour you can reproduce yourself: the portal shows bands for VMs the public API leaves empty.

Public (Resource Graph SpotResources)Internal (portal backend)
ScopeTenant-globalSubscription-scoped
CoveragePartialFuller
Who can call itAnyone with ReaderMicrosoft portal clients only
HistoryNone, current band onlyNone exposed to you

Even the freshness is ambiguous. Microsoft's own documentation describes the rate as covering the last 28 trailing days in one place and the last 7 days in another. That inconsistency is unresolved in the docs themselves.

Filling the gaps without lying to the user

The naive thing to do is show the Resource Graph band where it exists and a blank everywhere else. The problem is that a blank reads as "low risk" to a human, when it actually means "no data". That is the most dangerous possible default for a cost tool.

So where Resource Graph has no eviction band, the tool calls Microsoft's Spot Placement Score API (generally available, api-version=2025-06-05) live, and shows its High, Medium or Low signal instead. It answers a slightly different question, how likely a deployment is to succeed right now rather than how often the VM gets evicted, and Microsoft is explicit that a High score is not a guarantee against eviction. But for the combinations the public eviction table ignores, it is the best live risk signal Azure exposes, and it is honest about being a capacity signal rather than an eviction rate. The rule throughout: a missing band is "no data", never "safe".

None of the other APIs close the gap on their own. Retail Prices is pricing only. Resource SKUs tells you availability and restrictions, not eviction. The public Spot Advisor page is pricing-oriented, and unlike AWS, Azure publishes no machine-readable per-region eviction feed. The complete picture only exists if you stitch the sources together and record the history yourself.

What this means if you run spot

  • A point-in-time eviction rate lies. Bands move. The number that matters is the trend, and Azure does not keep it for you.
  • Treat a missing band as no data, not low risk. This is the trap that bites people building their own tooling.
  • Make geography and family work for you. GPU families churn hardest, a handful of regions stay calm, and that is a real cost lever for flexible workloads.
  • The upside is genuine. A 90% discount on identical hardware is not a gimmick. It is just only safe if you can see the risk, over time, not in a single snapshot.

The open question

I would genuinely like to be wrong about the buried API. If there is a supported, documented way to pull complete per-region eviction data programmatically, I have not found it, and neither did a fairly thorough trawl of the options above. If you work on Azure Compute and know otherwise, I would love to hear it.

Either way, this is exactly the friction the spot pricing tool exists to remove: live spot prices, real eviction rates, savings, regional alternatives, and the eviction history nobody else seems to keep, with the gaps filled by the best live signal available instead of a misleading blank.


Want spot prices and recorded eviction history for any Azure SKU, no sign-up? Try the Caleta spot pricing tool. Optimising a bigger Azure bill? Run a free Cost Review.

How mature is your cloud cost management?

Take our free 2-minute FinOps maturity test and get a personalised improvement roadmap.