FOCUS, and why comparing two clouds is harder than it should be

Every provider names, groups and dates its billing data differently, so multi-cloud cost reporting turns into a translation project. An open specification fixes the schema, and what it cannot fix is worth knowing before you build.

Ask a simple question across two clouds: what did compute cost us last month. On one, the answer sits in a column describing an instance family with a usage type that encodes region, tenancy and operating system in a single string. On the other, it is split across a service name and a meter category, with the discount applied as a separate negative line. On a third, the charge appears the day it was reconciled rather than the day the resource ran.

Nothing here is wrong. Each provider's schema reflects how that provider sells. The cost is that any organisation with more than one cloud spends real engineering time writing a translation layer, and the translation is never quite finished because the schemas change.

FOCUS, the FinOps Open Cost and Usage Specification, is the industry's answer: a common schema for billing data that providers publish alongside their native exports.

What it normalises

The value is in agreeing on the boring things, because the boring things are where the translation work is.

Column names and meanings. A defined set of columns with specified semantics, so BilledCost means the same thing everywhere and you stop maintaining a mapping table.

The cost columns that matter. The specification separates the amount actually invoiced from the amount before discounts and from the amortised view of a commitment. That distinction is the one teams most often get wrong when building their own reporting, because a reservation paid upfront shows as a large charge in one month and nothing afterwards unless you amortise it, and comparing an amortised view on one cloud against a billed view on another produces conclusions that are simply false.

Time. Defined charge periods, so a monthly total means a calendar month of usage rather than a billing cycle that starts on the day the account was created.

Resource and service identification. Consistent identifiers and a service category taxonomy, so compute is compute across providers.

Tags. A defined place for your own allocation tags, which is what makes cross-cloud attribution possible at all.

What it does not solve

Be clear about the limits, because the marketing tends not to be.

Normalisation loses provider-specific detail. The columns that make a native export useful for deep analysis of one cloud are not all in the common schema. Keep the native export as well; the normalised one is for comparison, not for replacing your primary source.

It does not make services comparable. A managed Kubernetes service and a serverless container platform both land in a compute category, and that does not make the cost per unit of work comparable. The specification fixes the schema, not the semantics of what you bought.

Adoption varies. Coverage differs by provider and by service, and the specification itself is versioned and still evolving. Check the current version supported by each of your providers and the known gaps before designing around a column.

It does not give you a warehouse. You still have to ingest, store and query the data, and on a large estate the volume is substantial.

Whether it is worth the work

The honest test is how many clouds you actually operate and who asks the question.

One cloud. Not worth it. The native tooling is better for a single provider and the effort is pure overhead. Revisit if an acquisition changes the answer.

Two or more clouds, with someone asking cross-cloud questions. Worth it. The alternative is a bespoke translation layer that one person understands and that breaks when a provider changes an export format.

A cost tooling vendor in the middle. Ask them whether they consume the normalised format. Increasingly they do, and it reduces their onboarding time and your lock-in to their model.

The clearest beneficiaries are organisations with a genuine multi-cloud estate, which in our experience is usually the result of acquisition or of a deliberate regulatory choice rather than a strategy. If you are in that position, the comparison questions are constant, and answering them from a map rather than four consoles is the same instinct as in nobody has seen the whole estate.

Building the pipeline

The shape is the same everywhere and takes a few weeks rather than a quarter.

Enable the export from each provider into object storage, ideally in the normalised format where supported, and keep the native export too. Land it in a query engine, partitioned by date and provider, because a full scan of a year of billing data on a large estate is expensive and you will do it by accident, which is exactly the failure described in BigQuery cost control.

Build a small number of derived views rather than letting everyone query raw: cost by team, cost by service category, cost by environment, and the amortised view of commitments. Publish those and keep the raw table for investigations.

Then reconcile monthly against each provider's own invoice total. This is the step teams skip and it is what keeps the pipeline trustworthy. A discrepancy is either a bug in your pipeline or a charge you did not know about, and both are worth finding.

The prerequisite nobody can skip

The specification normalises the provider's data. It cannot normalise yours.

If your tag keys differ between clouds, with Owner on one, owner on another and cost-centre on a third, cross-cloud attribution fails at the last step regardless of how good the schema is. Agree one small set of allocation tag keys and enforce it in each cloud's native policy engine, which is the same first step as in where the AWS bill hides and the Azure bill.

Do that before the pipeline. A normalised dataset with inconsistent tags is a faster way to produce the same unanswerable question.

The things people forget

  • Credits and refunds have their own columns. Ignoring them makes your reported cost higher than the invoice, and people stop trusting the report.
  • Currency. Multi-currency estates need a stated conversion approach, or month-on-month comparisons move for reasons that have nothing to do with usage.
  • Marketplace and third-party charges. Software bought through a cloud marketplace appears on the bill and is not infrastructure. Categorise it or your compute number is wrong.
  • Exports cost money. Billing exports to object storage and the queries over them are themselves a line item, and an unpartitioned daily full scan is a genuinely silly way to spend money on cost reporting.
  • Retention. Keep at least thirteen months so year-on-year comparison is possible.

What to do this week

Take the same question to both of your largest clouds: what did we spend on compute last month, amortised. Time how long it takes to answer each, and write down the two definitions you had to use. That gap is the case for normalisation, and if the answer took ten minutes on both, you do not have this problem and should spend the time elsewhere. We assess this in the cost phase of a cloud engagement.

ConsultorIA

Want this done on your cloud?

A ten-day read-only assessment is free, and Skyline lets you see your estate on a map before you write to us.

Related articles

Modules people reuse instead of copying

The two failures are a module that wraps one resource and adds nothing, and a module that does everything and nobody dares change. A minimal interface, safe defaults and honest versioning are what separate them.