Skip to main content
idle · azure

Running Azure VMs averaging under 5% CPU for 30 days, with the right fix for each

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

Azure VMs that stay running at under 5% `Percentage CPU` for 30 days bill full compute for almost no work. ZopNight checks memory and network activity too, then proposes one of three fixes: a recurring off-hours schedule, a review-then-deallocate for VMs idle in 95% of hours, or a smaller size when a reservation covers the VM.

Signal and threshold

How ZopNight evaluates Running Azure VMs averaging under 5% CPU for 30 days, with the right fix for each.
Field Value
Rule IDsRC-201
Categoryidle
Severitymedium
MetricPercentage CPU
Thresholdaverage below 5%
Evaluation window30d
SourceZopNight
Permissions usedMicrosoft.Compute/virtualMachines/read · Microsoft.Insights/Metrics/Read

Idle compute is billed exactly like busy compute

Azure bills a VM in the Running state for its full size. Microsoft’s VM states and billing table marks Running and Stopped (allocated) as billed and Deallocated as not billed, with the caveat that disks and networking keep charging. A VM that averages a few percent CPU all month costs the same compute as one at 80%.

Finding low-CPU VMs from the CLI

List the running VMs, then pull a month of hourly CPU, memory and network for a candidate:

Terminal window
az vm list -d \
--query "[?powerState=='VM running'].{name:name, group:resourceGroup, size:hardwareProfile.vmSize}" -o table
az monitor metrics list \
--resource /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Compute/virtualMachines/<vm> \
--metric "Percentage CPU" "Available Memory Percentage" "Network In Total" "Network Out Total" \
--aggregation Average Maximum --interval PT1H --offset 30d

Guards a VM must pass to count as idle

  1. The VM is running, and no known active schedule already parks it. VMs that ZopNight has measured as mostly off are also left alone.
  2. Average Percentage CPU over the last 30 days is below 5%.
  3. Memory is not the bottleneck: if available memory averages below 40% (more than 60% used), the VM is treated as a memory-bound workload such as a database or cache.
  4. Network is quiet: an average above 1 MB per sample on either Network In Total or Network Out Total suggests a proxy, gateway or replication target, and the VM is skipped.
  5. The VM has a positive monthly price.

Which fix you get, and when there is none

  • Reservation or savings plan coverage: deallocating does not refund a one- or three-year commitment, so the proposal is a smaller size, priced from real rates. No smaller size or no rate means no finding.
  • Idle in at least 95% of hours: measured from the VM’s own hourly CPU over at least 7 days of samples, this becomes a review-then-deallocate advisory. It is vetoed when a peak of 80% CPU recurs in most observed weeks (a scheduled job), when CPU reaches 30% in at least 5% of hours (routine short work), or when the name suggests a bastion, jump box, VPN, HA or DR node, or a stateful data service.
  • Everything else: a recurring off-hours schedule. With no measured idle share there is no finding, never a flat estimate. Dev and test schedules are also covered by Azure VM Non-Production Scheduling.

How each proposal is priced

Terminal window
schedule: saving = monthly cost x measured idle share of hours
review-deallocate: saving = compute portion only (managed disks keep billing)
smaller size: saving = VM monthly cost x (1 - smaller size rate / current size rate)

For a VM under a reservation or savings plan, the commitment keeps billing after the resize, so this saving is realised only when other VMs use the freed commitment (for example through reservation instance size flexibility) or the reservation is exchanged.

Acting on an idle VM

  1. Review CPU, memory and network in Azure Monitor and confirm with the owner that nothing depends on the VM around the clock.
  2. For the schedule proposal, set start and stop times rather than leaving the VM off for good. az vm auto-shutdown -g <rg> -n <vm> --time 1900 covers the nightly stop.
  3. For the deallocate review, run az vm deallocate -g <rg> -n <vm> once the owner agrees.
  4. For a VM covered by a reservation, resize with az vm resize -g <rg> -n <vm> --size <smaller-size> and review the commitment with whoever owns reservations, since the smaller VM may no longer match the reserved size.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

472 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

472 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·