All Articles
AzureFinOpsCloud

I Audited 25 Azure Bills. Here's Where the Money Actually Leaks.

After auditing dozens of Azure bills across enterprises and scaleups, the same five line items account for most of the waste. Here's what to look for first.

MGMohamed Ghassen BrahimMay 11, 20269 min read

After auditing more than 25 Azure bills — across reinsurers, energy companies, SaaS scaleups, and mid-market manufacturers — I can tell you that cloud waste is not random. The same five categories account for 70–85% of the overspend I find. Every time.

The total waste I've identified across those engagements runs well into seven figures of annual spend that organisations were paying without realising it. Not because their engineers are careless, but because Azure's defaults are generous to Microsoft and the tooling that should flag problems is either misconfigured or unmonitored.

Here is what I actually find, in order of frequency and impact.

35–60%
Avg. waste identified
As % of total Azure spend
#1
Compute right-sizing
Most common waste category
72hr
Orphaned resource age
Avg. before they're flagged
~40%
Reserved Instance savings
vs. pay-as-you-go

The Five Leak Points

1. Compute That Was Provisioned for a Launch and Never Right-Sized

This is the single largest waste category in every audit I conduct. The pattern is predictable: a new workload is provisioned, someone picks a VM size with headroom for "expected growth," growth does not arrive at the expected rate, and the over-provisioned VM runs at 8–15% average CPU utilisation for the next 18 months.

Azure Advisor will tell you about this. The problem is that nobody has configured Advisor alerts to actually fire, and the weekly digest email ends up in a distribution group that nobody reads.

In the most extreme case I encountered, a client was running a fleet of Standard_D16s_v3 instances (16 vCPUs, 64 GB RAM) for a batch processing workload that ran at under 10% peak CPU. Moving to Standard_D4s_v3 instances — with a reserved capacity commitment — reduced their compute bill for that workload by 73%. The workload performance was identical.

What to look for: Any VM or App Service plan running below 20% average CPU over a 30-day period. Azure Advisor's "Right-size or shutdown underutilised virtual machines" recommendation with a cost impact figure. AKS node pools where the average pod density is below 40%.

2. Orphaned Resources Accumulating Quietly

Managed disks attached to deleted VMs. Static public IPs associated with nothing. Load balancers with empty backend pools. Snapshots from 14 months ago that nobody has reviewed. Private endpoints that outlived the services they connected to.

None of these are large costs individually. Together, in mature Azure environments, they commonly account for €3,000–15,000 per month of pure waste — money paid for storage, networking, and management fabric attached to nothing useful.

The root cause is almost always the same: resources are created by engineers during development or incident response, provisioned in ways that bypass the IaC that would normally handle teardown, and then forgotten because there is no tagging policy that would surface them.

What to look for: Unattached managed disks (filter by "Disk state: Unattached" in the Azure Portal). Public IPs with no associated resource. Snapshots older than 90 days that have never been used for a restore. Use Azure Resource Graph queries to sweep across subscriptions — the portal view per subscription misses the scale.

⚠️

The tagging problem compounds this

If your Azure resources lack consistent owner and environment tags, you cannot attribute costs to teams, and you cannot automate cleanup. Every orphaned resource audit I run manually costs 4–6 hours of analyst time per subscription. A tagging policy enforced at subscription level via Azure Policy reduces that to a 20-minute script run.

3. Dev and Test Environments Running at Production Scale, 24/7

This is the most embarrassing category because it is the most avoidable. Development and staging environments provisioned to mirror production — full VM sizes, high-availability database tiers, Premium storage — and left running continuously, including nights and weekends.

The arithmetic is simple. A staging environment at 50% of production cost, running 168 hours per week, costs 168/40 = 4.2x what it would cost if it ran only during business hours (40 hours). Shut it down on evenings and weekends and you pay for 40 hours of actual use plus some fraction of persistent storage for the off-hours.

In practice, most non-production environments need to run between 8am and 8pm on weekdays. That is 60 hours out of 168, a 64% reduction in compute cost for those environments. For an environment costing €5,000/month at full run, that is €3,200/month recovered — from a scheduled shutdown script.

What to look for: Any VM, AKS cluster, or Azure SQL Database in a subscription tagged (or named) as dev, staging, or test that shows consistent cost every hour including nights and weekends. Azure Cost Management's "Cost by hour" view makes this obvious.

4. Unoptimised Storage Tiers and Data Retention

Azure Blob Storage has Hot, Cool, Cold, and Archive tiers. Most organisations put everything in Hot and leave it there. This costs approximately 5x more than Archive for data that is never accessed.

The specific pattern I find most often: application logs, database backups, and completed ETL outputs in Hot tier Blob Storage accounts, accumulating indefinitely, because the application that writes them was never given a lifecycle management policy that would transition or delete them.

A €10,000/month storage bill frequently has €4,000–6,000 of potential savings through lifecycle management alone. Setting a policy to transition blobs older than 30 days to Cool, older than 90 days to Cold, and delete after 365 days (or move to Archive for compliance) takes an afternoon to implement and costs nothing.

The second storage waste I find: Premium SSD for workloads that have no latency-sensitive I/O. A database server running at 15 IOPS peak does not need Premium SSD. Standard SSD at roughly 40% of the Premium cost performs identically at those workloads.

Storage TierRelative CostAccess LatencyIdeal Use Case
Hot Blob1x (baseline)MillisecondsFrequently accessed data
Cool Blob~0.5xMillisecondsInfrequently accessed, 30+ days
Cold Blob~0.2xMillisecondsRarely accessed, 90+ days
Archive Blob~0.04xHours (rehydration)Compliance retention, 180+ days
Standard SSD~0.4x vs PremiumLowMost database workloads under 10k IOPS
Standard HDD~0.15x vs PremiumHigherBackups, archival, cold workloads

5. Reserved Instances and Savings Plans — Purchased Incorrectly or Not at All

Reserved Instances (RIs) for compute, Azure SQL, and Cosmos DB offer 30–40% discounts for 1-year commitments and 55–65% for 3-year commitments versus pay-as-you-go pricing. In every audit I conduct on organisations spending more than €20,000/month on Azure, I find either no RI coverage at all, or RIs purchased for the wrong VM family that are providing minimal coverage.

The common mistakes:

No RIs on stable baseline workloads. Production web services, databases, and background workers that run 24/7 are exactly what Reserved Instances are designed for. Running them on pay-as-you-go pricing is paying a 40–65% premium for capacity flexibility you will never use.

RIs purchased for a VM SKU that the team later migrated away from. An RI for Standard_D8s_v3 provides no benefit if the workload moved to Standard_E8s_v5. Azure RI coverage reports surface this — many organisations never look at them.

Savings Plans underutilised. Azure Compute Savings Plans are more flexible than RIs (they apply across VM families and regions) and are appropriate when workloads are less predictable. They are significantly underused.

At a minimum, any workload running consistently for more than 6 months at meaningful scale should be covered by an RI or Savings Plan.

The Audit Process I Actually Run

When I audit an Azure bill, I run this sequence. The six steps span three days and move from data collection through targeted analysis to a final deletion candidate list:

Export 90 days of cost data by resourceDay 1

Pull from Azure Cost Management with resource-level granularity. Tag completeness audit first — if fewer than 70% of resources have owner and environment tags, the cost attribution work is a prerequisite to everything else.

Run Azure Advisor at subscription scopeDay 1

Export all recommendations to CSV. Filter to Cost category. Sort by estimated annual savings descending. The top 10 are almost always actionable.

Identify non-production environments and check run schedulesDay 2

For every non-production subscription or resource group, check hourly cost data. Any consistent spend during nights and weekends is a shutdown opportunity.

Storage tier auditDay 2

Query all storage accounts for tier distribution and last-access metadata. Check lifecycle management policies — if none exist, draft them. Calculate the tier-transition savings.

RI coverage reportDay 3

Pull the RI utilisation and coverage report from Cost Management. Identify uncovered compute, SQL, and Cosmos DB. Model the savings from a 1-year RI purchase on the stable baseline.

Orphaned resource sweepDay 3

Azure Resource Graph queries across all subscriptions for unattached disks, unused IPs, empty load balancers, and stale snapshots. Present as a deletion candidate list with cost impact.

What a Realistic Savings Picture Looks Like

Here is an anonymised example from a recent audit of a scaleup spending approximately €85,000/month on Azure:

CategoryMonthly Waste FoundAction RequiredTime to Implement
VM right-sizing (8 instances)€12,400Resize VMs, purchase RIs1 week
Dev/test shutdown automation€8,200Deploy Azure Automation runbooks2 days
Orphaned resources€3,600Delete confirmed orphans1 day
Storage tier migration€7,100Lifecycle management policies1 week
Reserved Instance gaps€9,800Purchase RIs for stable workloads1 day
Total€41,100/month3 weeks

That is a 48% reduction in their Azure bill, implemented in three weeks of engineering time, from a starting point of an organisation that considered itself cloud-cost-aware.

🔍

The FinOps mindset shift that matters most

Cloud cost optimisation is not a one-time project. The companies that sustain low waste rates treat cost as a product metric — tracked on the same dashboard as uptime and error rate, with a named owner per cost centre, reviewed weekly. The ones that do a cleanup every 18 months spend the intervening period re-accumulating the same waste.

Where to Start if You Have 2 Hours

If you cannot commit to a full audit right now, spend two hours on these three things:

  1. Open Azure Advisor → Cost tab. Look at the top recommendation by estimated annual savings. If it is greater than €10,000, that alone justifies a proper audit.
  2. Open Cost Management → pull the last 30 days of costs by resource group. Sort descending. The top 5 resource groups account for 60–80% of spend in most environments. Any of them look unfamiliar?
  3. Check your RI coverage report. If your compute coverage is below 60%, you are paying the pay-as-you-go premium on stable workloads. That is almost certainly the fastest money to recover.

Those two hours will tell you whether the waste is at the surface or embedded deeper. Either way, you will have a number and a starting point.


If your Azure bill has been climbing and you suspect there is more waste in it than anyone has time to investigate properly, let's talk — a focused cloud cost audit is one of the fastest ways to generate a concrete ROI number, and I've rarely seen an environment where it doesn't find at least 20% of recoverable spend.

Ready to act

Ready to put this into practice?

I help companies implement the strategies discussed here. Book a free 30-minute discovery call.

Schedule a Free Call