Azure VMs averaging 5 to 30% CPU that fit the next-smaller size in their family
What does ZopNight detect here?
ZopNight flags an Azure VM whose 30-day `Percentage CPU` average is at least 5% and under 30%, with memory use, network and disk operations at or below 60%, 10 MB/s and 500 per second. It names the next-smaller size in the same family that fits the observed peaks and prices the move from both sizes' real rates.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-275 |
| Category | rightsizing |
| Severity | medium |
| Metric | Percentage CPU, Available Memory Percentage, Network In/Out Total, disk operations |
| Threshold | avg CPU 5% to under 30%, memory used <= 60%, network <= 10 MB/s, disk ops <= 500/s |
| Evaluation window | 30d |
| Source | ZopNight |
| Permissions used | Microsoft.Compute/virtualMachines/read · Microsoft.Insights/Metrics/Read |
Where it applies
Paying for vCPUs a VM leaves unused all month
Azure bills a running VM for its size every hour, whatever the guest does with it. The resize guide confirms you can scale a VM down after creation, whether it is running or deallocated. A VM that spends the month at 15% CPU on an 8-vCPU size is usually paying for twice the cores it needs.
The trick is proving that the smaller size is safe. Average CPU alone is not enough: memory, network and disk limits also scale with size, and a VM that is quiet on CPU may still be memory-bound or storage-bound.
Pulling the four signals for a VM
az vm list --query "[].{name:name, rg:resourceGroup, size:hardwareProfile.vmSize}" -o table
az monitor metrics list --resource <vm-resource-id> \ --metric "Percentage CPU" "Available Memory Percentage" "Network In Total" "Network Out Total" \ --aggregation Average Maximum --interval PT1H --offset 30d
az vm list-vm-resize-options --resource-group my-rg --name my-vm -o tableAvailable Memory Percentage is free memory, so subtract it from 100 to get memory in use.
Utilization band and headroom tests
- Average CPU over 30 days is at least 5% and below 30%. Below 5% the VM is an idle candidate for Idle Azure VM; above 30% it is reasonably used.
- Memory in use averages 60% or less, when the memory metric is available.
- Average inbound and outbound network traffic each stay at or below 10 MB/s, and average disk read and write operations each stay at or below 500 per second, so the VM is not network- or storage-bound.
- The VM costs at least $20 a month.
- A next-smaller size in the same family fits the full-window CPU and memory peaks, not just the averages.
VMs that get no size recommendation
Members of a VM scale set and Databricks cluster VMs are skipped; their size is managed elsewhere. A burst-shaped peak, or a 95th percentile that would not fit the smaller size, stops the rule. Target sizes are currently named for the Dsv3, Dsv4, Dsv5, Dasv4, Dasv5, Esv3, Esv4, Esv5, Easv4, Easv5, Fsv2 and B-series families, so VMs in other families, such as M, L, N or Dv2 sizes, get no finding. Missing rates, a smaller size that is not cheaper, or a saving under $5 a month also mean no recommendation.
Pricing the step to the smaller size
monthly saving = VM monthly cost x (1 - smaller size hourly rate / current size hourly rate)Both are on-demand rates for the region. There is no fixed-percentage fallback when a rate is missing.
Resizing the VM
- Review the 30-day profile in VM Insights, paying attention to peaks.
- Resize during a maintenance window:
az vm resize --resource-group my-rg --name my-vm --size Standard_D4s_v5. - Update the size in your ARM, Bicep or Terraform definitions so the next deployment does not undo it.