The two common mistakes
- Oversized: a 2 TB Premium SSD (P40) bought "for performance" on a file server doing 200 IOPS.
- Undersized: a database data disk throttled at its IOPS cap while the VM has plenty of headroom (see the "disk is slow" troubleshooting post).
Both come from sizing without data.
1. Measure 2–4 weeks of real usage
Per disk, from Azure Monitor metrics (no agent needed):
| Metric | What it tells you |
|---|---|
| Data Disk IOPS Consumed Percentage | How close to the disk's IOPS limit |
| Data Disk Bandwidth Consumed Percentage | How close to the throughput limit |
| OS Disk IOPS/Bandwidth Consumed Percentage | Same for the OS disk |
| VM Cached/Uncached IOPS Consumed Percentage | Whether the VM limit, not the disk, is the ceiling |
| Composite Disk Read/Write Operations/sec | Actual IOPS |
Pull the p95 and max, not averages. Backups and month-end jobs matter.
az monitor metrics list --resource <vm-id> --metric "Data Disk IOPS Consumed Percentage" \
--interval PT1H --aggregation Maximum --offset 30d --dimension LUN -o table
2. Choose per disk
| Usage pattern | Good fit |
|---|---|
| Dev/test, low IO, interruptions acceptable | Standard SSD |
| Production, modest IO | Standard SSD or small Premium SSD |
| Production databases, steady IO | Premium SSD v2 (IOPS and MB/s set separately) or Premium SSD |
| Short bursts above baseline | Premium SSD with bursting (on supported sizes) |
| Extreme, sub-millisecond IO | Ultra Disk |
| Archives, backups on VM | Standard HDD only if latency doesn't matter |
3. Premium SSD v2: pay for what you use
With Premium SSD v2 you set capacity, IOPS and throughput separately. Every disk includes a baseline IOPS and MB/s, and you pay for extra above it. So a 2 TB disk doesn't have to carry P40-level IOPS charges.
az disk update -g rg-app -n sqldata01 --disk-iops-read-write 6000 --disk-mbps-read-write 250
IOPS and throughput can be changed online (with limits on how often). Constraints to check before choosing it: region and zone support, it can't be an OS disk, host caching isn't supported, and migration from Premium SSD has its own steps (snapshot/copy or the documented conversion path).
4. Premium SSD: performance tiers instead of bigger disks
If a Premium SSD needs more IOPS for a period (quarter-end, migration), raise its performance tier without growing the size:
az disk update -g rg-app -n sqldata01 --set tier=P40 # disk stays its current size
az disk update -g rg-app -n sqldata01 --set tier=P30 # lower again later (cooldown rules apply)
5. Shrinking isn't possible: plan the move
Managed disks can grow but not shrink. To go smaller:
- Add a new, right-sized disk.
- Copy data (robocopy, rsync, or database file moves / backup-restore).
- Swap drive letters/mount points, test, then delete the old disk.
Changing type (Premium ↔ Standard SSD) is a simple update when the VM is deallocated:
az vm deallocate -g rg-app -n web01
az disk update -g rg-app -n web01-data01 --sku StandardSSD_LRS
az vm start -g rg-app -n web01
6. Don't forget the VM limit
A disk faster than the VM's uncached limit is wasted money. Compare the sum of disk IOPS/MB/s against the VM size's uncached limits before upgrading disks. Sometimes the right fix is a VM size change.
7. Clean up
- Unattached disks:
az disk list --query "[?diskState=='Unattached'].[name,resourceGroup,diskSizeGb,sku.name]" -o table - Old snapshots: list by
timeCreated; keep what the backup policy needs.
Warning
Changing disk type or size on a clustered or database VM is a change: schedule it, take a backup or snapshot first, and confirm the application's own storage requirements (some vendors certify specific disk types).
Checklist
- 2–4 weeks of disk and VM-level metrics reviewed (p95/max)
- Type chosen per disk from usage
- Premium SSD v2 constraints checked before use
- Performance tiers used for temporary peaks
- VM uncached limits compared
- Unattached disks and stale snapshots removed