Most observability tools treat cloud and AI spend the way they treat CPU: a number that ticks up over time, stored next to your metrics, charted on the same axis. It reads well in a demo. It is also wrong in a way that quietly corrupts every dollar figure you show a finance team.
Bills are not append-only
A metric is a fact about a moment: this gauge was 0.72 at 14:03, and it will never be anything else. Money doesn't behave like that. A nightly billing estimate is a guess that gets corrected — the provider restates it as usage settles, then replaces it entirely when the invoice finalizes. A credit lands and rewrites a day you already recorded. If you append every version as a new time-series point, you are double-counting by construction.
So we made it a ledger
byteshift stores cost in Postgres, not in the telemetry store, and shapes it after the FOCUS billing standard: a billed-cost figure, explicit charge periods, and native provider extras kept alongside. Each row is upserted by (org, dedupe_key), so a restated day replaces its earlier estimate in place instead of stacking on top of it. Nightly estimates and finalized invoice items sit side by side, distinguished by basis, and the stats default to the nightly basis so a total never counts the same spend twice.
Billed-first, estimate-labelled
The payoff is honesty. The headline number on your cost and AI pages is real ledger money — what the provider will actually bill you — broken down by provider and service. When a self-reported figure is all that exists for a cut a bill can't attribute (spend per person, say), it is shown clearly as an estimate, never blended into the billed total. Empty carries coverage, so “we have no data yet” can never masquerade as “you spent zero.”
The rule of thumb
If a number can be restated after you first record it, it wants a ledger, not a metric. Infrastructure gauges still flow as telemetry — those really are facts about a moment. Dollars get the ledger they deserve.