The Azure Well-Architected Cost Optimization Pillar: Finding the Waste in Your Azure Bill
One Azure Well-Architected cost review surfaced roughly EUR 180,000 a year of waste in a mid-market estate: orphaned resources, oversized SKUs, retention nobody chose. What I look for, and where Azure Advisor stops.
The Azure Well-Architected Cost Optimization Pillar: Finding the Waste in Your Azure Bill
Roughly EUR 180,000 a year.
That is what one structured cost review surfaced in a single mid-market Azure environment. Orphaned resources. Over-provisioned SKUs. Retention settings nobody had touched since the day the workspace was created. The team running the estate had not seen any of it, and I want to be fair to them about why: they were running the thing, not auditing it. Those are different jobs and nobody had ever given them the second one.
The number didn’t surprise me. It is roughly what accrues when an Azure estate grows under delivery pressure for two or three years and no one holds a budget against the architecture. Nothing dramatic happens along the way. A hundred small defaults, each perfectly reasonable on the day it was chosen, compound into a bill that nobody in the room can fully explain.
The cost optimization pillar is the discipline of explaining it.
The principles are boring
Every euro of spend should map to a workload requirement, and that mapping should be reviewed rather than assumed. The Well-Architected Framework frames cost optimization as a continuous discipline, not a one-time cleanup. True. But the first review is always where the big numbers fall out, for the obvious reason that nobody has done the cleanup yet.
Four things, none of them clever. Build a cost model, so you know what a workload is supposed to cost. Put governance in place, so spend cannot grow unobserved. Monitor it. Right-size to actual demand instead of imagined demand.
That’s the whole pillar.
Every finding I write up comes from the gap between one of those four and an estate where it was never enforced. And governance is the root cause of most of the rest. Create resources without mandatory tags (cost centre, owner, environment, workload) and you have lost the ability to attribute spend at all. Untagged spend is unaccountable spend, and unaccountable spend is exactly where waste hides, because nobody owns it enough to question it.
Resources that outlive the thing they belonged to
You delete what you meant to delete. Azure leaves behind everything that was attached to it. There is no cascade, the pattern repeats across resource types, and every one of the leftovers keeps billing for nothing.
Managed disks are the classic. Delete a virtual machine through the portal and, depending on how it was created, the OS and data disks often stay right where they were. A Premium SSD you are no longer using bills at its full provisioned rate regardless of whether anything reads from it. So the query is simple: enumerate every managed disk where diskState is Unattached, sum the monthly cost. In a three-year-old estate that is routinely dozens of disks.
Public IPs do the same thing. A static public IP not associated with any network interface, load balancer, or gateway still carries an hourly charge. They accumulate as load balancers and VMs get decommissioned and the IP reservation quietly outlives them.
Then App Service plans. The plan is the compute you actually pay for; the apps just run on it. Delete the last app and the plan carries on billing at its tier, happily, forever. A Standard or Premium plan hosting zero sites is pure waste.
It does not stop there. Orphaned NAT gateways. Unused Application Gateways. Disk snapshots taken for a migration two years ago and never cleaned up. A Bastion host left running in a subscription nobody opens anymore.
Each one is small. Together they are a line item.
The largest line in most bills is oversizing
At provisioning time the safe choice is to size up. Nobody ever sizes back down once the real load is known.
That is the entire mechanism, and it produces the single largest category of waste I find. It is the mirror image of the performance efficiency pillar, where the finding runs the other way: under-provisioning, no autoscale, and a workload that falls over at month-end.
The cause is human rather than technical. A workload goes onto a Standard_D8s_v5 (eight vCPUs) because the team did not yet know the load and over-sizing felt prudent. The load turned out to be modest. Eighteen months later that VM is still running at 8% average CPU. The right size was a Standard_D2s_v5, at roughly a quarter of the cost. Nobody downsized it, because downsizing carries a small risk and precisely no one gets rewarded for taking it.
Databases tell the same story. An Azure SQL Database sitting at a vCore count picked for a launch-day peak that never materialised. An Azure Cache for Redis on Premium where Standard would carry the throughput comfortably. The work is correlating the provisioned SKU against actual utilisation from Azure Monitor and producing a right-sizing list with the euro delta attached to each resource.
If you want one place to start, start here. Not with the orphans. The orphans are more satisfying to delete, but this is where the money is.
| Waste category | How it accrues | Where I find it |
|---|---|---|
| Orphaned disks | VM deleted, disk left behind | Managed disks with diskState: Unattached |
| Idle public IPs | Parent resource decommissioned | Public IPs with no associated resource |
| Empty App Service plans | Last app deleted, plan remains | Plans with zero associated sites |
| Over-provisioned VMs | Sized for a peak that never came | Sustained CPU well below SKU capacity |
| Misconfigured retention | Default or excessive retention set once | Log Analytics / backup retention vs requirement |
| Missing reservations | Steady-state workloads billed at pay-as-you-go | Consistent usage with no reservation applied |
Retention is a rate times a number nobody chose
Multiply a per-gigabyte rate by a duration nobody set deliberately and the bill grows every single day the data sits there. Two settings drive almost all of it: Log Analytics workspace retention and backup retention.
A workspace ingesting diagnostic and platform logs has a retention period. Set it to two years across a high-volume workspace and you are paying to store telemetry long past any operational or compliance need anyone can point at. The retention baselines that DORA and NIS2 actually require are far shorter than the multi-year figures some workspaces drift into.
To be clear, this is not the “retention is too short” finding. That one is a security finding and it lives over in the WAF security pillar. Here it is the exact opposite problem, billed monthly.
Backup retention has the same shape. Azure Backup policies with daily, weekly, monthly, and yearly recovery points held well past the actual recovery requirement. Every retained recovery point is storage you pay for. Set the retention to a default, never align it to a documented RPO, and the cost compounds against data nobody was ever going to restore.
Where Azure Advisor stops
“We already look at Advisor, isn’t that the same thing?”
Fair question, and I get it on most engagements. Advisor surfaces individual resource-level cost recommendations: idle resources, right-sizing candidates, reservation opportunities. It is genuinely useful and any cost review should read it first. Then it stops at the boundary of a single resource, and there are three things on the other side of that boundary.
Architectural waste is the first. Advisor will tell you a VM is under-utilised. It will not tell you the workload belongs on a different service entirely, that a set of always-on VMs should be a serverless or containerised design costing a fraction of that at this load. That is an architecture judgment, not a resource recommendation.
Your policy is the second. Advisor has no idea what your retention requirement is, or your reservation strategy. It gives you the generic recommendation. It cannot tell you that this specific workspace breaches your own 180-day standard, because it has never seen your standard.
Third, it cannot connect cost to compliance. The same misconfigured retention that wastes money may also breach an evidence requirement. Advisor sees the euros. It does not see the governance posture those euros are sitting inside.
The evidence is a query that returns nothing
The proof of a fixed estate is not a spreadsheet of savings. Anyone can produce a spreadsheet of savings.
It is an Azure Resource Graph query that comes back with zero orphaned disks, zero idle public IPs, mandatory tags present on every resource, and reservation coverage on the workloads that were always going to run anyway. Every resource maps to an owner and a workload. Run the query, get nothing back, that’s the evidence.
That state is a governance artifact as much as a financial one. An estate where spend is fully attributed is one where Azure Policy enforces tagging at creation, budgets alert at thresholds, and reservations reflect a deliberate commitment rather than an accident. The EUR 180,000 was never a one-time recovery. It was the symptom of governance that had never been enforced, and if you clean it up without fixing that, I will find the same money again in two years.
The durable fix is the enforcement. Not the cleanup.
Which is roughly why I built Platform Architecture Authority. I got tired of doing the same query-by-hand archaeology on every engagement, writing the same six findings into a different logo’s document, and watching the estate drift back within a year because the report was a PDF and PDFs do not enforce anything. So it reads the estate, attaches the euro figure to each waste category, and emits the remediation as infrastructure-as-code you review before you apply it. Read-only, and it proposes rather than disposes. A FinOps lead still decides which reservations to commit to and which workloads genuinely need their headroom.
What sticks
- Orphaned resources (unattached disks, idle public IPs, empty App Service plans) accrue silently because deleting the parent does not delete them.
- Over-provisioned SKUs are the largest single category of waste. Sized for a peak that never arrived, running 24/7 at the wrong tier.
- Log and backup retention quietly multiplies storage cost when it was set once and never aligned to a requirement.
- Missing reservations and savings plans leave a meaningful discount on the table for steady-state workloads that will run regardless.
- Azure Advisor surfaces some of this and stops at the resource level. It cannot see architectural waste and it does not know your policy.
- The bill is an accumulation of decisions, most of which were never decisions at all. A cost review turns the defaults back into choices.
FAQ
How does a single assessment find EUR 180,000 in annual waste? It accrues across categories: over-provisioned VMs and databases running 24/7 at the wrong tier, orphaned disks and IPs billing for nothing, retention set far beyond requirement, and steady-state workloads with no reserved instances. No single item is dramatic. The total is what three years of unaudited defaults produce in a mid-market estate.
Will deleting orphaned resources break anything? Genuinely orphaned resources (an unattached disk, a public IP with no associated resource, an App Service plan with no apps) have no dependents by definition, so deleting them is low risk. The discipline is confirming the orphaned state in Azure Resource Graph before deletion, and snapshotting anything where data recovery is conceivable.
Does cost optimization conflict with reliability? It can. Geo-redundant storage and zone redundancy cost more, and aggressive cost cutting can strip out necessary resilience. The resolution is the documented RTO and RPO from the reliability pillar: redundancy is justified where the recovery objective requires it, and is waste where it does not.