Outcome
By the end of this lesson, you will be able to explain why org totals include a residual that showback views deliberately do not, locate unattributed spend, and reason about the CUR 2.0 source and credit handling.
| Tier | Architect |
| JTBD | ”Make our headline number reconcile with the invoice, without pretending we can attribute what we cannot.” |
| Personas | FinOps Lead · Finance Partner · Engineering Leader |
| Prerequisites | M3.5.L1 · T0.M0.4 (rack rate vs billing cost) |
| Time | 9 minutes |
| Bloom verb | Explain (Understand), Locate (Apply), Reason (Evaluate) |
1. Concept
Some billing line items never match a discovered resource, and no amount of tagging discipline changes that.
WHAT NEVER MATCHES networking and data-transfer charges taxes and fees AWS rows carrying no resource id at all services ZopNight does not discover AWS history older than 14 days, where only service-level granularity existsThese are stored under a sentinel resource id of the form svc:<service>[:<region>], so they are kept rather than discarded.
The residual, and where it is added
FOR BILLING-ENABLED ORGS, Summary and Trends add aPER-DATE RESIDUAL on top of the resource-level totals:
max(0, billed - captured)
It appears as its own field and is INCLUDED in theheadline total, so the headline RECONCILES WITH THEINVOICE instead of silently under-reporting.The max(0, ...) matters: where captured exceeds billed for a date, the residual is zero rather than negative. It is a floor, not a signed correction.
Where it is deliberately NOT added
This is the design decision that makes showback trustworthy, and it is worth being able to state.
ADDED (org totals) Summary, Trends, per-provider summary, and the internal admin dashboard's cost surfaces
NOT ADDED (showback views) Breakdown, Snapshots, Teams, Tags, K8s
BECAUSE: SHOWBACK IS NOT THE INVOICE.
Unattributed spend has no resource to attribute, sofolding it into a team or tag view would mean inventingan owner for spend that has none.ALSO NOT ADDED: RBAC-SCOPED VIEWS.
A team-scoped user's view skips the residual entirely,because the spend has no resource to scope by. Adding itwould show a scoped user spend that is not theirs andthat they cannot drill into.So two numbers in the product disagree, legitimately, and you can now say why. The org total reconciles with the invoice. The team view attributes what can be attributed. Knowing that difference is what lets you defend both figures in the same meeting.
It is folded everywhere consistently
The residual is applied to every org-total surface so they cannot disagree with each other: the summary, the trends, the per-provider breakdown (where billing_records carries a provider, making it attributable at that level), and the internal admin dashboard.
It also rides the gRPC contract, so the MCP get_costs tool can label the invoice-reconciliation component rather than reporting an unexplained inflated total to an agent.
Two data-handling details worth knowing
COLLISION MERGING Unmatched records collapsing onto the same sentinel id are MERGED (summed) BEFORE UPSERT. Without that, the unique key would keep only the last colliding row and the residual would under-count.
NEGATIVE LINE ITEMS Credits and refunds are stored and overlaid AS-IS, negative. They are not filtered out.
An FX conversion failure, NOT a negative sign, is the only thing that leaves a cost column null.That second point is the one that answers “why is our total lower this month than the sum of our resources”: a large credit is a real negative line item and it belongs in the total.
The CUR 2.0 source, and what it changes
OPT-IN. AWS accounts whose credentials carry the exportbucket and name have per-resource billing read from thecustomer's own Data Exports (CUR 2.0) gzip-CSV in S3,INSTEAD OF Cost Explorer.
WHAT IT BUYS 1. It LIFTS THE 14-DAY RESOURCE-LEVEL LIMIT. Backfill stays at resource granularity for the export's whole history, rather than collapsing to service-level beyond 14 days. 2. It ingests EVERY invoice line-item type: taxes, fees, credits, refunds, reservation and savings-plan rows.
Unmatched rows still flow to the svc: sentinel as usual.The first point is the one that changes reporting materially. Without CUR 2.0, anything older than 14 days on AWS has no resource attribution available at all, so historical showback simply cannot be reconstructed. With it, it can.
FAILURE BEHAVIOUR S3 access denials surface as `no_permission` in billing sync status. Other export errors FAIL THE SYNC EXPLICITLY rather than silently degrading to the 14-day API.That last clause is the important guarantee: a broken CUR export does not quietly become a lower-fidelity data source that nobody notices. You get an error, not a downgrade.
GCP is net of credits
The BigQuery export's cost column is PRE-CREDIT.
The daily per-resource and service-level queries foldthe (negative) credit amounts into each row withNUMERIC-exact math, so committed-use, sustained-use andpromotional discounts are reflected the way the invoicebills them.
Credit-only rows (zero cost, nonzero credits) are NOTdropped.A GCP figure that ignored credits would overstate spend by the entire value of the customer’s CUD and SUD discounts, which is exactly the population most likely to be looking closely.
2. Demo
Reconciling a month, and explaining a discrepancy that was not one:
THE CHALLENGE "Your Teams report totals $412,000. Your Summary says $448,700. Which one do we take to the board?"
BOTH. FOR DIFFERENT QUESTIONS.
Summary $448,700 resource-attributed $412,000 unattributed residual $36,700 data transfer $19,400 taxes and fees $8,100 NoResourceId rows $6,200 undiscovered services $3,000
AWS invoice for the month $448,700 EXACT
Teams report $412,000 Every dollar attributed to an owning team. The $36,700 is ABSENT BY DESIGN: it has no resource, so it has no team.
THE ANSWER GIVEN "Summary for the board, because it reconciles with the invoice. Teams for the chargeback conversation, because every dollar in it has an owner. The $36,700 gap is data transfer, taxes and untagged services, and inventing an owner for it would make the chargeback dishonest."
That answer was accepted and the two-number reporting became standard.
THE SECOND FINDING $19,400 of data transfer in one month was itself worth investigating. It had been invisible while the team looked only at the Teams report, because it never had a resource to appear against.
Unattributed spend is not just an accounting residual. It is frequently where the un-owned waste lives.
THE CUR 2.0 DECISION They wanted per-resource history for the previous year. On Cost Explorer, anything older than 14 days has only service-level granularity, so it could not be reconstructed.
They enabled the CUR 2.0 export. Backfill then carried resource granularity across the whole export history, and taxes, fees, credits and savings-plan rows came in as line items instead of being absent.
One caution they were given: if S3 access is later revoked, the sync FAILS EXPLICITLY as no_permission rather than quietly falling back to the 14-day API. An error is the intended outcome, not a silent downgrade.3. Hands-on (6 min)
1. Compare, for last month: Summary total $______ Teams report total $______ Difference $______ That difference is your unattributed residual.
2. Break the residual down. What is in it? data transfer $______ taxes and fees $______ no-resource-id rows $______ undiscovered services $______
3. Is the largest component something you could act on? ______________________________________________ (Data transfer usually is.)
4. Compare Summary against the actual invoice: Summary $______ invoice $______ Do they reconcile? Y / N If not, check whether billing sync is complete for every account.
5. On AWS: are you using Cost Explorer or a CUR 2.0 export? ____________________ If Cost Explorer, note that per-resource history older than 14 days is not reconstructable.4. Knowledge check
Q1
Why is the unattributed residual added to Summary and Trends but not to the Teams or Tags views?
A. Because showback is not the invoice
B. Because showback views are cached and would be stale
C. Because the residual is provider-level and teams are cross-provider
D. Because it would double-count against resource-level rows
Show answer
Correct: A. Unattributed spend has no resource to attribute, so folding it into a team or tag view would mean inventing an owner for spend that has none. Org totals reconcile with the invoice; showback attributes what can be attributed. Views limited to one team skip it too, for the same reason. You cannot filter by a resource that does not exist, so including it would show somebody spend that is not theirs and that they cannot open.
Q2
An AWS org enables the CUR 2.0 export instead of Cost Explorer. The most significant reporting change:
A. The costs become amortized rather than unblended right across the whole of the commitment term in the export
B. The 14-day resource-level limit is lifted, so backfill carries resource granularity across the export’s whole history
C. The unmatched rows stop appearing in the unattributed residual bucket altogether from then on
D. The credits are excluded from the reported total from that point onward in every report
Show answer
Correct: B. On Cost Explorer, anything older than 14 days has only service-level granularity, so historical per-resource showback simply cannot be reconstructed. It also ingests every invoice line-item type including taxes, fees, credits, refunds and reservation rows. Unmatched rows still flow to the svc: sentinel as before, so C is wrong.
Q3
A GCP org’s monthly figure would be materially overstated if credits were ignored. How are they handled?
A. Credits are applied as a single monthly adjustment at the organisation level, so a per-resource view never sees them at all and the monthly total is already net
B. The daily per-resource and service-level queries fold the negative credit amounts into each row with exact numeric math, because the BigQuery export’s cost column is pre-credit
C. Credits are excluded entirely, and the invoice is used instead of the export whenever a reconciliation against finance is actually needed for the month
D. GCP costs are stored pre-credit and then adjusted at read time, so the stored rows are gross and every query has to subtract the credits out for itself
Show answer
Correct: B. Credit-only rows carrying zero cost and nonzero credits are not dropped. Ignoring them would overstate spend by the entire value of the customer’s committed-use and sustained-use discounts, which is exactly the population most likely to be checking the numbers closely.
5. Apply
Report two numbers routinely: the org total that reconciles with the invoice, and the attributed total that has an owner for every dollar. Explaining the gap once establishes both; letting someone discover it undermines both.
Then look at what is actually in your residual. Data transfer with no resource to appear against is invisible on every showback view and is frequently the largest single un-owned line in the estate.
Related lessons
- L1: Organisation, Teams, Tags: pick the dimension
- L2: Team attribution and shared resources
- T0.M0.4.L4: The two-source cost model
- T5.M5.4.L3: Network architecture and egress cost
Glossary terms touched
Unattributed spend · Sentinel resource id · CUR 2.0 · Net of credits