All Articles
Deep Dive·6 min read

Why Your Azure VM Costs Doubled Last Month

Azure bills surprise teams every month. Here are the five things most likely responsible for your unexpected cost spike — and exactly how to fix each one.

Part of: Microsoft Azure Cloud Engineer

You opened the Azure Cost Management dashboard and saw a number you did not expect. The VM is the same size it was last month. Nothing changed — except the bill. Here is where the money actually went.

1. The VM Ran When Nobody Was Using It

This is the single most common cause of unexpected Azure costs. VMs running 24/7 for development or testing workloads that are only used during business hours waste 65% of their runtime.

A Standard_D4s_v3 (4 vCPUs, 16GB RAM) costs approximately $140/month on-demand. If you only need it 8 hours a day on weekdays, that is 40 hours out of 168 — 76% idle.

Fix: Auto-shutdown

In the Azure Portal → VM → Operations → Auto-shutdown → Enable → Set time → Done.

Or via CLI:

az vm auto-shutdown \ --resource-group myRG \ --name myVM \ --time 1900 \ --email alerts@yourcompany.com

For development environments, go further with Azure DevTest Labs — VMs start on a schedule and shut down automatically. Multiple developers share the same policy.

2. You Are Over-Provisioned

Azure VM sizing is usually done once, at provisioning time, based on a guess about peak load. Six months later the VM is at 15% average CPU utilisation and nobody has revisited the size.

Check your actual utilisation:

# View CPU metrics for the last 30 days az monitor metrics list \ --resource /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Compute/virtualMachines/{vm} \ --metric "Percentage CPU" \ --start-time 2026-03-06 \ --end-time 2026-04-06 \ --interval P1D \ --aggregation Average

If average CPU is below 20% and memory is below 40%, you are likely over-provisioned by one or two size tiers.

Fix: Resize the VM (takes 1-2 minutes of downtime):

az vm resize \ --resource-group myRG \ --name myVM \ --size Standard_D2s_v3

Going from Standard_D4s_v3 to Standard_D2s_v3 saves ~$70/month. For 10 VMs that is $700/month for one afternoon of work.

3. Unattached Managed Disks

When you delete a VM in Azure, the managed disk is not deleted by default. It sits there, detached, accruing charges — typically $10-20/month per disk for a 128GB Premium SSD.

Teams that frequently create and tear down test VMs accumulate dozens of these.

Find all unattached disks:

az disk list \ --query "[?diskState=='Unattached'].[name, resourceGroup, diskSizeGb, sku.name]" \ --output table

Delete them:

az disk delete \ --resource-group myRG \ --name myOrphanedDisk \ --yes

Do this for snapshots too — they persist indefinitely:

az snapshot list \ --query "[].{Name:name, RG:resourceGroup, Size:diskSizeGb}" \ --output table

4. Premium SSD Where Standard SSD Suffices

Azure defaults to Premium SSD (P-series) for many VM sizes. Premium SSD costs roughly 4x Standard SSD for the same capacity. For dev/test environments, logs, or any non-latency-critical storage, this is wasteful.

| Disk type | 128GB/month | |---|---| | Standard HDD | ~$6 | | Standard SSD | ~$12 | | Premium SSD | ~$20 | | Ultra Disk | ~$130+ |

Check disk type:

az disk list \ --query "[].{Name:name, Sku:sku.name, SizeGB:diskSizeGb}" \ --output table

Downgrade without data loss (VM must be deallocated):

az disk update \ --resource-group myRG \ --name myDataDisk \ --sku Standard_LRS

5. Data Egress You Did Not Notice

Azure charges for data leaving Azure regions. Inbound traffic is free. Outbound is not.

Common sources of surprise egress:

  • ▸Application logs shipped to an external logging service (Datadog, Splunk) from Azure VMs
  • ▸Database backups written to a non-Azure destination
  • ▸VMs in one region communicating with services in another region (cross-region transfer is billed)
  • ▸Large API responses sent to end-users without compression

Check egress in Cost Management: Azure Portal → Cost Management → Cost Analysis → Filter by Meter Category: Bandwidth

Egress rates vary by region but are typically $0.08-0.087/GB out to the internet.

Fix options:

  • ▸Use Azure Monitor / Log Analytics instead of third-party logging for Azure-native workloads
  • ▸Enable gzip compression on your web server or API
  • ▸Colocate services in the same region
  • ▸Use Azure CDN to cache static content close to users (reduces origin egress)

Finding the Root Cause Fast

Azure Cost Management shows a cost breakdown by resource and meter. Use it before guessing:

Portal → Cost Management + Billing → Cost Analysis
→ Group by: Resource
→ Sort by: Cost (descending)
→ Look at the top 5 resources

Then drill into the top offender and group by Meter to see whether the cost is compute, storage, or bandwidth.

Cost spikes almost always have a simple cause. The dashboard tells you exactly where to look — most teams just do not check it until after the bill arrives.

#Azure#Cloud Cost#FinOps#Virtual Machines

Want to go deeper?

Microsoft Azure Cloud Engineer

View Course