Managing virtual machines (VMs) efficiently in Azure isn’t just about provisioning and running workloads, it’s also about understanding how billing and resource consumption behave when those VMs are not in use. One common point of confusion, even for seasoned Azure admins, is the difference between stopping a VM and deallocating it.
These two actions aren’t interchangeable, and misunderstanding them can quietly inflate your Azure bill for no reason.
In this article, I’ll break down exactly what happens behind the scenes when you stop vs. deallocate an Azure VM, show how to properly deallocate VMs, and highlight common pitfalls to avoid so you don’t accidentally pay for compute you’re not using.
If you’d like to see the official Microsoft Learn document on the various VM states, look no further – States and billing status of Azure Virtual Machines | Microsoft Learn
Key Concepts
- Stopped (but not deallocated) – When a VM is stopped from inside the OS (for example, using Windows’
shutdownor Linux’sshutdowncommand), the VM is powered off, but the compute resources (and associated costs) are still reserved.- You’re still paying for the VM’s compute.
- Stopped (deallocated) – When a VM is stopped and deallocated from Azure, the VM is powered off and its compute resources (like CPU and memory allocation) are released.
- You stop incurring compute charges, though storage costs (for OS disk, data disks, and snapshots) still apply.
Deallocating VMs Properly
Using the Azure Portal
- Go to Virtual Machines in the Azure Portal.
- Select the VM you want to deallocate.
- Click the Stop button in the toolbar.
- Wait for the VM status to show Stopped (deallocated).
Tip: If you’re stopping multiple VMs, you can select them all and stop them all at once.
Using Azure CLI
If you prefer using the CLI then you can stop VM’s using the commands shown below –
# Deallocate a single VM
az vm deallocate --resource-group myResourceGroup --name myVM
# Deallocate all VMs in a resource group
for vm in $(az vm list --resource-group myResourceGroup --query "[].name" -o tsv); do
az vm deallocate --resource-group myResourceGroup --name $vm
done
How to Check VM Status (CLI)
az vm get-instance-view --resource-group myResourceGroup --name myVM --query "instanceView.statuses[?starts_with(code, 'PowerState/')].displayStatus" -o tsv

Using PowerShell
If you prefer PowerShell like I do then you can also manage VM’s as per the examples below –
# Deallocate a single VM
Stop-AzVM -ResourceGroupName "myResourceGroup" -Name "myVM" -Force
# Deallocate all VMs in a resource group
$resourceGroup = "myResourceGroup"
Get-AzVM -ResourceGroupName $resourceGroup | ForEach-Object {
Stop-AzVM -ResourceGroupName $_.ResourceGroupName -Name $_.Name -Force
}
How to Check VM Status (PowerShell)
# Get the power state of a VM
$vm = Get-AzVM -ResourceGroupName "myResourceGroup" -Name "myVM" -Status
$vm.Statuses | Where-Object { $_.Code -like "PowerState/*" } | Select-Object DisplayStatus

Common Pitfalls and How to Avoid Them
- Forgetting about storage costs
Even when deallocated, VMs incur storage charges for their OS disk and attached disks. Plan accordingly if you intend to leave VMs deallocated for long periods. - Public IPs without static reservation
If your VM has a dynamic public IP, deallocating it will release the IP. Use a static public IP if you want to preserve the same IP when restarting. - Automation scripts neglect deallocation
Ensure your automation (like DevTest labs, VM scale sets, or custom scripts) explicitly deallocates VMs if the goal is cost savings.
Understanding the difference between stopping and deallocating Azure VMs is crucial for cost optimization and resource management.








Leave a comment