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.
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
# 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# 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.