Skip to main content
Back to the Azure Footguns Database
CostHighCommonAZF-0022

An oversized VM runs at single-digit CPU while billing for a SKU the workload never uses

A VM sits at a fraction of its provisioned CPU and memory, so you pay for a SKU far larger than the workload uses. Nothing is broken, so nothing prompts a resize.

Footgun ID
AZF-0022 (Azure Footgun No. 22)
Azure service
Azure Virtual Machines
Resource type
Microsoft.Compute/virtualMachines
Updated
July 1, 2026

What it is

A virtual machine whose real utilization sits well below the size it was provisioned at, often single-digit CPU with memory to spare. The VM works fine, so it never draws attention, but you pay the full hourly rate for a SKU the workload never grows into.

Impact (cost)
~$210/month at list price for the gap between a D8s_v5 and the D2s_v5 the workload actually needs
Basis: Azure list price. Figures are estimates, not measurements.

Why it happens

VMs get sized once, up front, against a guess about peak load, and the guess is almost always generous. Someone picks a comfortable SKU during a project, the workload turns out smaller than feared, and the size is never revisited because a right-sized VM and an over-sized VM behave identically day to day.

Azure bills a VM on its provisioned SKU, not on the CPU and memory it actually uses, so an idle Standard_D8s_v5 costs exactly what a fully loaded one does. There is no built-in nudge that says "this machine peaked at 8% CPU over the last quarter, you are paying for four times the cores it needs." The signal only shows up if you go looking at metrics over a long enough window to rule out normal quiet periods.

What it costs / blast radius

The cost is the gap between what you provisioned and what the workload needs, and for compute that gap is large. A Standard_D8s_v5 (8 vCPU) runs roughly $280/month at Linux pay-as-you-go list price; the Standard_D2s_v5 (2 vCPU) a low-CPU workload actually needs runs roughly $70/month, so the oversizing is about $210/month for that one VM. (List price; reserved instances, Windows licensing, and spot all shift the number.) A workload with low, intermittent usage may belong on a burstable B-series SKU instead, widening the gap further. Multiply by a fleet where over-provisioning is the default and it becomes one of the largest quiet line items on the bill.

See it

Find them: check a VM's CPU utilization over a long window before trusting its size
# Pull daily-average Percentage CPU for the last 30 days.
# Average and peak (max) both stuck in the single digits mean the SKU is far larger than the workload.
az monitor metrics list \
  --resource "$VM_ID" \
  --metric "Percentage CPU" \
  --interval P1D \
  --start-time "$(date -u -v-30d '+%Y-%m-%dT%H:%M:%SZ')" \
  --aggregation Average Maximum \
  --query "value[0].timeseries[0].data[].{day:timeStamp, avg:average, max:maximum}" \
  --output table
Fix: resize to a SKU that fits the measured load (keep safety headroom)
# Resizing stops and restarts the VM, so schedule a window.
# Leave headroom above the observed peak (max); do not size to the average exactly.
az vm resize \
  --resource-group rg-prod \
  --name vm-app-01 \
  --size Standard_D2s_v5   # down from Standard_D8s_v5

# For low, intermittent usage, a burstable B-series SKU may fit better still.

How StratoLens helps

StratoLens analyzes long-window utilization for every VM across every subscription, profiles the workload (compute, memory, balanced, or burstable), and surfaces a right-sizing recommendation with a confidence score and the monthly savings, so an oversized machine can't hide behind "it works fine." You don't have to pull metrics VM by VM; the analysis runs continuously in your own tenant.

Start Your 28-Day Free Trial

Every feature unlocked. Deploys to your Azure tenant. No data leaves your tenant.

Available now on the Azure Marketplace.

Built for Azure infrastructure teams who need complete visibility across their entire estate.