Post-Migration Cost Optimisation Is a Phase, Not an Afterthought
The migration project ended last month. Everyone celebrated. The servers are in Azure. The on-prem data centre is being decommissioned. The architecture is solid. The first full month's Azure bill arrived yesterday.
It was 40% over projection.
Why migration cost estimates are always wrong
Migration cost estimates are based on assumptions that don't survive contact with production:
Azure Migrate recommendations are conservative. The tool recommends VM sizes based on peak on-prem utilisation plus headroom. On-prem VMs are almost always over-provisioned because storage was cheap and nobody wanted to risk performance issues. Azure Migrate doesn't right-size — it migrates what exists with Microsoft's sizing guidance layered on top. Those recommendations are safe. Safe means over-provisioned.
Hybrid costs are invisible during migration. While running on-prem and Azure simultaneously, you're paying for both. This is necessary during the transition, but migration budgets rarely account for the full duration of hybrid operations. A three-month migration that takes six months doubles the hybrid cost line item.
Data egress is never accounted for properly. VPN traffic, cross-region replication, backup data transfer — these show up as line items that didn't exist on-prem. They're not large individually. Collectively, they add 5-10% to the bill.
The optimisation sprint
After the first bill arrived, I spent three weeks on nothing but cost optimisation:
Right-sizing. I pulled 30 days of actual performance data for every VM. Average CPU utilisation: 12%. Average memory utilisation: 35%. I downsized almost every VM by one or two SKU levels. Some by three. A Standard_D8s_v5 became a D4s_v5. A D4s_v5 became a D2s_v5. Total savings: about 25% of compute spend, with no performance impact.
Reserved Instances. Everything that's running 24/7 in production got a one-year reservation. 30-40% savings on compute for those workloads. The commitment made finance nervous until I showed them the break-even: reservations pay for themselves in month four. Everything after that is savings.
Storage tiering. Half our storage was on Premium SSD that didn't need to be. Log volumes, archive data, backup staging — all moved to Standard HDD or Standard SSD. Premium is for production databases and high-IOPS workloads. Everything else is standard. Storage costs dropped by 40%.
Idle resources. The orphaned resource cleanup found: three unattached Premium SSDs, two unused public IPs, an Azure Bastion host in a subscription that nobody was using, and a Log Analytics workspace with no retention policy ingesting 40GB/day of debug logs from dev environments. Total waste: about $800/month.
The ongoing discipline
Cost optimisation isn't a one-time sprint. It's a recurring practice:
- Monthly: review the cost dashboard, check for unexpected line items, verify budget alerts are configured
- Quarterly: review VM sizing against actual utilisation, adjust reservations as workload patterns change, run the orphaned resource cleanup script
- Annually: renegotiate reservations based on the year's actual usage patterns
The first optimisation sprint is always the biggest savings. After that, it's maintenance — a few hundred dollars here, a few hundred there. But cumulatively, it adds up. The environment I optimised last year is running at about 60% of its initial Azure cost, with the same workloads and better performance.
Cloud cost management is like flossing. Nobody wants to do it. Everyone who does it regularly has fewer expensive emergencies.