There is a published FinOps maturity model. There are several. They are mostly fine, in the way that maturity models are mostly fine: a useful taxonomy that ages out the moment a real estate is in front of you. The thing they all share, and the thing none of them actually measure, is whether the practice survives a tag audit.
A tag audit is a simple thing. You take the cost-and-usage report. You sample 200 line items above a non-trivial cost threshold. You ask the team to tell you, line by line, which product, team, environment, and customer-segment each one belongs to. You stop when you’ve reached either certainty or 200, and you write down what fraction the team got right without checking the bill itself.
That number — the fraction the team can correctly attribute, cold — is a cleaner measure of FinOps maturity than the published frameworks. A team that scores 95% has a real practice. A team that scores 50% has a slide deck. The model below ranks six checkpoints by what each holds up under scrutiny.
Level 0: The dashboards exist. Nobody looks at them.
Most cloud estates above a few thousand a month have dashboards. Cost Explorer is on. Azure Cost Management is on. GCP Billing is on. There may be a third-party tool layered on top. The dashboards exist.
What’s missing at Level 0 is anyone whose job description includes reading them. Spend is reviewed once a quarter, by finance, with no context on what changed. Engineering is unaware of cost movements until a dashboard hits a finance threshold and finance sends an email. The conversation that follows is reactive, blame-shaped, and produces a one-off cleanup that rarely sticks.
A tag audit at Level 0 returns a number around 30%. Most spend can’t be attributed to a product or team without forensic work. The team isn’t doing FinOps. The team is reacting to bills.
Level 1: Spend has owners. The owners can see their numbers.
The first real step. Each cost centre has an owner. Each owner can pull a report — even if it’s a manual one — that shows the spend they’re accountable for. Tag coverage is improving but not enforced. New resources are meant to be tagged; some are.
A team at Level 1 can answer “how much did this product cost last month”. A team at Level 2 can answer “and why did it move”.
The conversation has shifted from reactive to introspective. Owners can see their numbers, but they’re not yet acting on them in real time. Anomalies are caught the following month, in the report. The savings work that happens is one-off — a Reserved Instance buy, a manual rightsizing pass — and isn’t on a recurring cadence.
A tag audit at Level 1 returns 60-70%. The 30-40% gap is mostly platform-shared resources, untagged historical state, and a long tail of cost types the policy doesn’t cover (data transfer, support charges, marketplace).
Level 2: Tags are enforced at provisioning, not after.
This is the inflection point. Tags become a precondition for resource creation, not a follow-up. Terraform modules require them. Service control policies refuse untagged resources in production accounts. CI pipelines fail builds whose IaC doesn’t carry the team, product, environment, and cost-centre keys.
The tag audit number at Level 2 jumps to 85-90%. The remaining 10-15% is legacy resources from before the policy, third-party integrations the policy can’t cover, and the always-present long tail of services that handle tags inconsistently across the cloud’s own surface area.
The behavioural shift is bigger than the number. Engineers stop seeing tags as bureaucracy and start seeing them as the thing that lets them ship without finance breathing down their neck. That shift, more than any tooling change, is what makes the next levels possible.
# A standard module's required tags. The module fails to plan if any are missing.
variable "team" { type = string }
variable "product" { type = string }
variable "environment" { type = string }
variable "cost_centre" { type = string }
locals {
required_tags = {
Team = var.team
Product = var.product
Environment = var.environment
CostCentre = var.cost_centre
ManagedBy = "terraform"
Module = "standard-service@v3.4.1"
}
}
# A platform-level SCP refuses ec2:RunInstances without the four required keys.
# The pipeline catches this earlier, but the SCP is the backstop.
Level 3: Anomaly detection is closed-loop.
A team at Level 3 doesn’t only see anomalies. The team has a defined process for what happens when one is detected. The anomaly opens a ticket. The ticket goes to the owner of the affected cost centre. The owner has a defined window to respond. If the response is “expected, here’s why”, the anomaly is closed with a documented reason. If the response is “investigating”, a follow-up triggers automatically.
This is closed-loop FinOps. The team isn’t just visible to itself; it’s accountable to itself. The dashboard is a queue, not a museum. Anomalies are resolved within days, not next-month-when-the-finance-meeting-happens.
The tag audit number at Level 3 stays around 90%. The lift from Level 2 is operational, not data: same data, more discipline. The savings the team books at Level 3 are larger than at Level 2, not because tagging improved, but because the team is now acting on the tags they have.
Level 4: Engineering decisions are cost-aware in design, not in retrospect.
The real maturity signal. Architecture decisions reference unit economics. The design document for a new service includes an estimated monthly cost at the expected request rate, broken down by cloud service. The decision to use one storage tier over another is made with reference to that estimate. The decision to deploy multi-region is costed before the call is made.
This sounds aspirational. In practice, it requires three things: a unit-cost reference document the team trusts; a culture where it’s normal to ask “how much will this cost”; and reviewers who push back on designs that aren’t costed. None of those are tooling. All of them are organisational.
Teams that reach Level 4 stop being surprised by their bills. The bill is roughly what the design said it would be, and when it isn’t, the variance is the prompt for a specific investigation rather than a generic alarm. Forecasts are accurate to within 5-10% on a quarter horizon, because the forecast is the rolled-up sum of design estimates plus a known variance term, not a finance-led extrapolation from last quarter’s number.
A tag audit at Level 4 returns above 95%. The team has, by this point, automated most of the remaining attribution gap.
Level 5: FinOps is a deletion practice.
The level above “doing it right” is “doing less of it”. A team at Level 5 spends as much energy on deletion as on optimisation. Idle resources are reaped automatically — old dev environments, orphaned EBS volumes, snapshots from migrations that completed two years ago, log buckets whose data is past its retention window.
The discipline at Level 5 is not technical; the technical part is straightforward. The discipline is willingness to delete things. Most cloud estates accumulate a layer of “we’ll deal with that later” that never gets dealt with, because the cost of leaving it is small enough at any given moment that nobody fights for the deletion. Level 5 teams have made deletion a recurring operational task with a named owner, a target percentage of estate volume to remove per quarter, and a review of what was deleted.
The savings from deletion are usually larger than the team expects, because untouched resources accrete. The savings from avoidance — the resources never created because the deletion habit has become design awareness — are larger still, and uncounted.
A tag audit at Level 5 returns 98%+. More importantly, the audit takes less time, because the estate is smaller. The cleanest sign of a mature FinOps practice is that there is less to audit.
What the slide deck always gets wrong
Maturity models like this one — including this one — invite a particular failure mode: a team reads the levels, declares itself somewhere on the ladder, and stops. The level becomes the achievement.
The actual maturity is the audit number, run on a recurring schedule. A team that’s at Level 3 by description but pulls 60% in an audit is not at Level 3. A team that’s at Level 4 by description but is rerunning the audit quarterly is at Level 4 because the audit number has held over time, not because it hit the number once.
The audit is also the only honest input to a commitment ladder. A FinOps team without trustworthy attribution is a FinOps team that cannot defensibly size commitments, justify chargebacks, or forecast spend. Everything else stacks on top of the audit number, which is why we keep coming back to it.
What good looks like across all six
A practice that runs through all six levels — and that survives an actual audit — has a specific operational rhythm. Tags are a precondition, enforced in code. Anomalies are a queue, with named owners. Design reviews include cost. Deletion is on a calendar. The audit is run quarterly, by someone independent of the engineering teams, with the result reported at the same level as security findings.
The estates we read most often live somewhere between Level 1 and Level 3. The work to move up two levels is not glamorous. It’s policy in modules. It’s queue discipline. It’s a culture conversation about whether deleting things is allowed. None of those are technical projects. All of them are recoverable in a quarter or two with focused attention.
Run the audit. The number you walk away with is the only level that matters.