Compute

How to Identify and Deallocate Idle Azure Virtual Machines

When a virtual machine is shut down from inside the guest OS, Microsoft Azure transitions the instance into 'PowerState/stopped' instead of 'PowerState/deallocated'. In this state, Azure retains the underlying compute hardware allocation and continues charging full hourly compute rates.

Odinext Cloud Engineering

Azure Infrastructure & FinOps Research

Published: August 10, 2025
6 min read
(Updated: August 15, 2025)

The Stopped vs. Deallocated State Trap

One of the most frequent sources of unexpected Azure billing is the subtle difference between shutting down an instance from the operating system versus deallocating it via the Azure control plane.

When an engineer executes `shutdown -h now` on Linux or clicks 'Shut Down' in Windows Server, the OS powers off, but Azure marks the VM status as PowerState/stopped. Because CPU cores and physical memory slots remain dedicated on the Azure hypervisor, compute charges continue to accrue at 100% of the provisioned rate.

Billing Alert

Only virtual machines in 'PowerState/deallocated' stop billing compute cores. OS and data disk storage fees continue until the attached disks are deleted.

Querying Azure Resource Graph for Stopped Instances

To locate all virtual machines across your tenant that are currently stopped but still incurring compute billing, you can execute a Kusto query via the Azure Resource Graph Explorer:

Azure Resource Graph Query
kusto
Resources
| where type =~ 'microsoft.compute/virtualmachines'
| extend powerState = tostring(properties.extended.instanceView.powerState.code)
| where powerState =~ 'PowerState/stopped'
| project name, resourceGroup, subscriptionId, location, properties.hardwareProfile.vmSize

Detecting Low-Utilization VMs (<5% CPU)

Beyond completely stopped instances, oversized development and staging VMs often run 24/7 with near-zero activity. WasteRadar analyzes 14-day telemetry curves from Azure Monitor to identify instances averaging under 5% CPU utilization.

For these workloads, engineers can either downscale the instance to a burstable B-series SKU (such as Standard_B2s or Standard_B2ms) or schedule automated deallocation during off-peak hours.

Automated & CLI Remediation Commands

To properly deallocate a stopped virtual machine and release its compute reservation, execute the following Azure CLI command:

Azure CLI Deallocation
bash
# Deallocate a single stopped VM
az vm deallocate --resource-group rg-workloads --name vm-batch-worker

# Check the confirmed power state
az vm get-instance-view --resource-group rg-workloads --name vm-batch-worker --query "instanceView.statuses[?starts_with(code, 'PowerState/')].code" -o tsv

Preventing Compute Waste with WasteRadar

Manual CLI queries require ongoing developer effort. Odinext WasteRadar runs automated daily discovery scans across all subscriptions, calculating the exact dollar impact using live Azure Retail Prices meters and dispatching proactive alerts to Slack and email before monthly invoices close.

Odinext Cloud Engineering

Azure Infrastructure & FinOps Research

The Odinext engineering team specializes in Azure cost management, ARM resource optimization, and automated cloud waste detection across enterprise multi-subscription architectures.

Automate This Analysis with WasteRadar

Stop running manual resource queries and spreadsheets. Odinext WasteRadar detects idle compute, unattached disks, and orphaned snapshots automatically with 100% read-only Azure IAM integration.

Related Technical Guides

Continue exploring Azure cloud cost optimization and FinOps architecture