FOCUS is an excellent normalization layer for cloud bills, and the conformance work across AWS, Azure, GCP, and OCI has made cross-cloud reporting genuinely tractable. But the spec was built from billing exports — and your datacenter, your colocation contract, and your flat-fee SaaS seats do not produce billing exports. There is no native FOCUS row for a depreciating server or a $480,000/year annual license. The result is that hybrid practitioners either leave 30–60% of their estate out of the FOCUS dataset entirely or hand-stuff rows in ways that quietly violate the spec's own column semantics. This article gives you a disciplined method for manufacturing conformant FOCUS rows for on-prem and SaaS spend — using BilledCost, EffectiveCost, ChargeCategory, and ServiceCategory the way the spec intends — so your hybrid estate lands in one queryable dataset instead of three disconnected ones.
- FOCUS 1.1 normalizes cloud billing data, but it has no ingestion path for cost sources that never produce a bill — owned hardware, colo space, and annual SaaS contracts are all silent.
- The most common hybrid mistake is dropping on-prem entirely; the second most common is stuffing a server's full purchase price into a single month's BilledCost, which destroys every trended report you build on top of it.
- BilledCost and EffectiveCost mean different things for an amortized asset: BilledCost is the cash event (often zero in a given month), EffectiveCost is the amortized slice. Getting this backwards is the single biggest source of corrupted hybrid FOCUS data.
- ChargeCategory = "Purchase" with a matching amortization charge is how the spec already handles cloud commitments — you reuse exactly that pattern for a capitalized server.
- Flat-fee SaaS is a unit-economics problem disguised as a billing problem: the contract gives you one number per year, so you must synthesize a daily EffectiveCost and a denominator (seats, tenants, API calls) before the data is useful.
- Keep a ChargeCategory or a custom x_CostSource tag that flags every synthesized row, so a downstream consumer can always separate "this came from a real export" from "this we manufactured."
Why FOCUS goes quiet at the datacenter door
The FinOps Open Cost and Usage Specification did the hard, unglamorous work of agreeing on what a cost column means across providers. Before FOCUS, "cost" might be unblended, blended, amortized, or net-of-credits depending on which CSV you opened. FOCUS 1.1 fixes that with a defined set of columns — BilledCost, EffectiveCost, ListCost, ChargeCategory, ServiceCategory, ResourceId, and the rest — and a conformance program that the major clouds now publish against.
But every one of those columns assumes an upstream billing system that emitted a charge. That assumption holds for AWS, Azure, GCP, and OCI. It collapses for the three cost categories that define a hybrid estate: owned hardware that was capitalized years ago, colocation contracts billed as a flat monthly facility fee, and SaaS purchased as an annual seat block. None of these produce a per-resource, per-hour billing export. FOCUS has no opinion on them because there is no source file to ingest.
This is not a flaw in FOCUS. It is a scope boundary. The problem is that practitioners treat the boundary as if it were a wall — they normalize the cloud, ship a beautiful unified dashboard, and footnote the datacenter as "not yet in FOCUS." In a 60/40 cloud-to-on-prem estate, that footnote is 40% of the money.
The two failure modes, and why the second is worse
When teams do try to bring on-prem into their FOCUS dataset, they fail in one of two ways.
Failure mode one: omission. The datacenter simply never enters the dataset. Reports are technically clean and completely misleading. Any allocation that compares team A (cloud-heavy) to team B (on-prem-heavy) is structurally biased toward making the cloud team look expensive and the on-prem team look free. I have watched real chargeback disputes get resolved in the wrong direction for exactly this reason.
Failure mode two: lump-sum injection. Someone takes a $90,000 server purchase and writes it into a single month's BilledCost with a made-up ResourceId. This feels like progress and is actively destructive. Every month-over-month trend now has a $90,000 spike that no engineering decision caused. Every unit-economics metric built on monthly cost is wrong for that month. And because the row used BilledCost rather than an amortized EffectiveCost, it is semantically lying about what FOCUS says that column means.
Omission gives you an incomplete picture. Lump-sum injection gives you a picture that is confidently wrong, which is worse, because people act on it.
Use the columns the way the spec already uses them for commitments
Here is the insight that makes the whole problem tractable: FOCUS already solved amortization — for cloud commitments. When you buy a three-year Savings Plan or a Reserved Instance up front, a conformant export does not put the entire prepayment in one month's EffectiveCost. It records a ChargeCategory of "Purchase" for the cash event and then emits amortized "Usage" rows over the commitment term. You reuse that exact pattern for a capitalized server.
Map an owned asset to FOCUS columns like this:
| FOCUS column | On-prem server value | Notes |
|---|---|---|
| ChargeCategory | "Purchase" (month of acquisition), then "Usage" (each amortized month) | Mirrors the commitment pattern |
| BilledCost | $90,000 in acquisition month; $0 thereafter | The actual cash event, once |
| EffectiveCost | $2,500/month over 36 months | Straight-line amortization slice |
| ServiceCategory | "Compute" | Use the same controlled vocabulary as cloud rows |
| ResourceId | CMDB asset tag (e.g. srv-dc1-00482) | Stable, joinable to your inventory |
| BillingPeriodStart / End | Calendar month boundaries | Align to the cloud invoice cycle |
| x_CostSource (custom) | "synthesized-onprem" | Flags non-export rows; see below |
Now your trended reports use EffectiveCost and see a smooth $2,500/month, exactly as they would for an amortized RI. Anyone who needs the cash view queries BilledCost and sees the $90,000 land once. The two columns tell two true stories instead of one false one. Add power, cooling, rack, and a loaded ops-labor allocation as additional amortized rows against the same ResourceId and you have a defensible fully-burdened unit cost — the method I laid out in the CapEx-to-OpEx piece, now expressed in spec-conformant columns.
Colocation: a facility fee is a shared cost, not a resource
Colo is its own shape. You do not own the building, but you pay a flat monthly fee for power, space, and cross-connects that covers many workloads at once. The mistake is treating the whole invoice as one undifferentiated line. A colo facility fee is a shared cost that needs a driver, the same way a Kubernetes cluster's cost needs a driver to split across namespaces.
Synthesize one FOCUS row per consuming workload, with EffectiveCost derived from an allocation key — power draw per rack unit is the most defensible, kW-hours is the gold standard if your PDUs are metered. Set ChargeCategory to "Usage", ServiceCategory to the closest match (often "Compute" or a custom facility category), and carry a x_AllocationBasis tag recording which driver you used. If two teams later dispute the split, the driver is the answer, not a meeting.
Flat-fee SaaS is a unit-economics problem in billing clothing
SaaS is the category most teams forget belongs in FOCUS at all — and it is often the fastest-growing line in a hybrid estate. A $480,000/year observability or data-platform contract arrives as one number. FOCUS wants daily or hourly granularity. So you synthesize it: divide the annual commitment into a daily EffectiveCost of roughly $1,315, set ChargeCategory to "Usage", and — this is the part that matters — attach a denominator.
A flat fee with no denominator is just a number you cannot manage. With one, it becomes a unit cost you can trend and challenge:
| SaaS contract | Annual EffectiveCost | Denominator | Synthesized unit cost |
|---|---|---|---|
| Observability platform | $480,000 | 2.1 TB ingested/day | $0.63 / GB ingested |
| Data warehouse (committed) | $1,200,000 | 18,000 query-hours/mo | $5.56 / query-hour |
| Identity / SSO seats | $96,000 | 4,000 active seats | $24 / seat / year |
Once that unit cost exists in the same dataset as your cloud and on-prem rows, the renewal conversation changes. "We pay $480K for observability" invites a shrug. "We pay $0.63/GB ingested and 40% of that volume is debug logs from one service nobody reads" invites action. The whole point of dragging SaaS into FOCUS is to make flat fees behave like the variable costs they secretly are.
The one rule that keeps the dataset trustworthy
Every row you did not get from a real billing export must be flagged. Carry a custom x_CostSource column with values like cloud-export, synthesized-onprem, synthesized-colo, and synthesized-saas. FOCUS explicitly allows provider- and practitioner-defined columns prefixed with x_, so this is conformant, not a hack.
This flag does three jobs. It lets a skeptical finance partner reconcile only the synthesized rows against contracts and POs. It lets you quantify how much of your "unified" picture is measured versus modeled — a healthy hybrid dataset might be 70% export-derived and 30% synthesized, and you should know which. And it gives you a clean migration path: the day a colo provider or SaaS vendor finally ships a usage API, you swap the synthesized rows for real ones and the flag disappears for that source. Without the flag, you can never tell what is real, and the entire dataset inherits the trust level of its least defensible row.
FOCUS gave hybrid practitioners a shared language. It did not give us a parser for the half of the estate that never speaks in invoices. That part is on us — and done with discipline, it is a few hundred synthesized rows a month, not a platform project.
Subscribe to the Hybrid FinOps brief for practitioner methodology updates, including a FOCUS column-mapping worksheet for on-prem, colo, and SaaS spend.
Frequently asked questions
Does FOCUS support on-premises and private cloud cost data?
Not natively. FOCUS 1.1 is built to normalize billing exports from cloud providers, and on-prem, colo, and flat-fee SaaS do not produce per-resource billing exports. You can still bring them in by synthesizing conformant rows — mapping a capitalized asset's amortized cost to EffectiveCost, the cash event to BilledCost, and using a Purchase/Usage ChargeCategory pattern that mirrors how the spec already handles cloud commitments.
What is the difference between BilledCost and EffectiveCost for an owned server?
BilledCost is the actual cash event — the full purchase price, recorded once in the acquisition month and zero thereafter. EffectiveCost is the amortized slice, e.g. $2,500/month over a 36-month life. Trended and unit-economics reports should run on EffectiveCost so you see a smooth monthly cost; cash-flow views run on BilledCost. Putting the full purchase price into a single month's EffectiveCost is the most common way hybrid FOCUS datasets get corrupted.
How do you put a flat-fee SaaS contract into FOCUS?
Divide the annual commitment into a daily EffectiveCost (a $480,000 contract is roughly $1,315/day), set ChargeCategory to "Usage", and — critically — attach a usage denominator such as GB ingested, query-hours, or active seats. The denominator converts a flat fee into a unit cost you can trend and challenge at renewal. Without it, the SaaS line is just a number you cannot manage.
How should colocation facility fees be allocated in FOCUS?
Treat a flat colo facility fee as a shared cost that needs a driver, not a single line item. Synthesize one row per consuming workload with EffectiveCost derived from an allocation key — metered kW-hours per rack is the most defensible, power draw per rack unit is a workable proxy. Record the driver in a custom x_AllocationBasis column so split disputes are settled by the data rather than by negotiation.
How do you keep a hybrid FOCUS dataset trustworthy when some rows are manufactured?
Tag every non-export row with a custom x_CostSource column (cloud-export, synthesized-onprem, synthesized-colo, synthesized-saas). FOCUS permits practitioner-defined x_ columns, so this is conformant. The flag lets finance reconcile only synthesized rows against contracts, lets you measure how much of the dataset is modeled versus measured, and gives you a clean path to swap synthesized rows for real ones when a provider eventually ships a usage API.
Is synthesizing FOCUS rows for on-prem a violation of the specification?
No, provided you respect the column semantics. The spec defines what each column means, not that every row must originate from a vendor export. Using ChargeCategory "Purchase" plus amortized "Usage" rows for a capitalized asset reuses the exact pattern FOCUS applies to cloud commitments. The violation is not synthesis — it is misusing columns, such as stuffing a full purchase price into EffectiveCost or omitting the x_CostSource flag that tells consumers the row was modeled.
Sources
- FOCUS Specification — FinOps Foundation
- FOCUS Column Definitions — FinOps Foundation
- FOCUS 1.1 Release Overview — FinOps Foundation
- FinOps for Data Center with FOCUS — FinOps Foundation
- FinOps Framework: Data Ingestion Capability — FinOps Foundation
- FinOps Framework: Managing SaaS Cost — FinOps Foundation
- AWS Data Exports for FOCUS 1.0 — Amazon Web Services
- What is FOCUS — Microsoft Learn
- Export Cloud Billing data in FOCUS format — Google Cloud
- Hybrid Cloud Cost Visibility and Allocation — CloudAware
If this kind of analysis is useful, the Hybrid FinOps brief ships one essay every two weeks. Subscribe to the Hybrid FinOps brief.