Outcome
By the end of this lesson, you will be able to describe the two-source cost model and pick the right source for any cost question.
| Tier | Operator |
| JTBD | ”Have one cost model that everyone uses the same way.” |
| Personas | FinOps Analyst · Engineering Leader · Finance Partner |
| Prerequisites | L1, L2, L3 |
| Time | 10 minutes |
| Bloom verb | Describe (Understand) and Pick (Apply) |
1. Concept
Keep two cost numbers, not one.
One is calculated live from what is running and the public price list. The other is the actual billed amount, after discounts, which arrives a day late. Label both clearly, and choose between them depending on the question being asked.
This is the pattern any serious cost practice ends up at, and it is what ZopNight implements.
Why two sources
A single-source cost model breaks under one of three pressures:
Freshness against accuracy. Billing data is at least a day behind. A calculated figure is available now. With only one of them you can either spot a problem today or reconcile an invoice correctly, but not both.
Before discount against after discount. A savings claim needs the rack rate, because that is the money you stopped spending. A budget needs the billed amount, because that is what was paid. One column cannot answer both without being wrong somewhere.
Gaps in coverage. Not every account has billing data wired up, and a new account will be running resources before it does. A calculated figure means there is a cost from day one rather than a blank.
The model
TWO COLUMNS, ONE TABLE─────────────────────────────────────────────────────────────cost_usd = live calculated rack rate pricing API × hours running × units ALWAYS available, ZERO lag, NO discount
actual_cost_usd = post-discount billing cost (provider source) from CUR / Cost Explorer / Cost Mgmt 24-48 hr lag, post-discount, NULL if not yet synced
cost_source = label: 'calculated' or 'actual' tells the reader which column is authoritativeHow aggregations work
ZopNight uses a single SQL expression, costColumn(hasBilling), across every aggregate query:
-- If ALL cloud accounts have billing sync, use actual_cost_usd everywhere-- Otherwise fall back to cost_usd (rack rate) for consistencySELECT COALESCE(actual_cost_usd, cost_usd) AS costFROM cost_recordsWHERE...The hasBilling predicate is resolved once per organization (cached for 60 seconds) and applied identically across summary, MTD, provider, budget, showback, and trends queries. The result: every number on every report comes from the same logic, no per-report drift.
The cost-source label
Every report header carries the label “Unblended Cost” (when actual is used) or “Rack Rate” (when calculated is used). The label is the contract with the reader:
- Unblended Cost = billed, post-discount, lagged. Use for: budgets, chargeback, monthly close.
- Rack Rate = calculated, pre-discount, live. Use for: savings claims, anomaly detection, live monitoring.
A report that does not name its column is leaking trust. The two-source model is what makes the label honest.
When a single source is sufficient
There are organizations where a single source is fine:
- Very small, single-account. Calculated cost is close enough; the discount stack is minimal.
- Single-cloud, billing pipeline mature. If billing data is consistently fresh and the discount stack is well-understood, the actual column alone may serve.
But for any multi-account, multi-cloud, or governance-heavy environment, the two-source model is the defensible posture.
The mistake the two-source model prevents
Three common errors disappear when both columns are present and labelled:
- The “we don’t know what we paid yet” stall. A team waits for monthly close to know last week’s cost. The live calculated column unblocks them.
- The “I thought we had a discount” surprise. Finance reports a rack-rate-flavored number. The bill arrives lower. Trust degrades. Two columns labelled explicitly prevent this.
- The over-claimed savings. A scheduling rollout is reported at billed-cost savings (much smaller than the rack-rate savings). The team loses sponsor confidence. Rack rate, labelled, is the right number for the claim.
Two sources, labelled, picked per question.
Per-row vs per-rollup
cost_source is per-row in cost_records. Rollup tables (daily / monthly aggregates) derive their own cost_source:
actualif any contributing row isactualcalculatedotherwise
A daily roll-up that is partially actual and partially calculated is labelled actual (with a tooltip explaining the partial state). Users reading the daily number get the most-recent best answer.
2. Demo
Same resource, same week, both columns visible:
RESOURCE: i-0abc123def (m5.large, us-east-1, RI-covered)
DATE cost_usd (rack) actual_cost_usd (billed) cost_source─────────────────────────────────────────────────────────────────────2026-05-13 $2.30 $1.49 actual2026-05-14 $2.30 $1.49 actual2026-05-15 $2.30 $1.49 actual2026-05-16 $2.30 $1.49 actual2026-05-17 $2.30 $1.49 actual2026-05-18 $2.30 NULL calculated2026-05-19 $2.30 NULL calculated ← billing sync lag─────────────────────────────────────────────────────────────────────WEEK rack rate $16.10WEEK billing (actual) $7.45 (5 days × $1.49)WEEK using COALESCE $12.05 ($7.45 + $4.60 fallback)The COALESCE pattern gives the best-available-answer per day: actual where available, calculated where not. The week label is actual (because some days were actual) but the rendered tooltip notes the partial fallback.
3. Hands-on (6 min)
For your own organization, evaluate:
1. Do you currently maintain both columns (live + billed) in your cost data? Y / N
2. If N: which one is your default? What gap does the missing column create? Default: __________ Missing column gap: __________
3. Which report uses which column? Budget reports: __________ (should be billed) Savings claims: __________ (should be rack rate) Anomaly detection: __________ (should be live) Monthly close: __________ (should be billed)
4. Are the columns labelled visibly on the report? Y / NIf any “should be” doesn’t match what is, the report is structurally lying. The fix is either to swap the column source or to switch the report’s stated purpose.
Ask for it instead. The same task you just did in the console, asked in one sentence.
BEFORE A ZopNight account with one cloud connected. Billing sync run at least once.ASK "Show the cost trend for last quarter, and tell me when billing data last synced."CHECK the sync timestamp before you trust the last few days. Recent days are usually incomplete, not cheap.Tools behind it: get_cost_trends (read, Cost), get_billing_sync_status (read, Cost), get_currency_exchange_rate (read, Cost). The full catalogue is at zop.dev/learn/mcp-tools.
4. Knowledge check
Q1
A new cloud account is connected to ZopNight at 10 AM. At 2 PM, what cost data is available for that account?
A. Nothing until tomorrow
B. Only the billed cost
C. The live calculated cost (rack rate) is available immediately; the billed cost lands within 24-48 hours
D. Only the resource list appears, and no cost figures at all until the billing sync lands in
Show answer
Correct: C. The two-source model guarantees live calculated cost from day one. The billed cost arrives when the billing sync catches up.
Q2
A team’s monthly variance report uses live calculated cost. Most likely consequence:
A. The report systematically overstates spend by the discount stack (typically 20-40%)
B. The report is accurate
C. The report is entirely irrelevant and ought simply to be ignored completely
D. The budget is wrong
Show answer
Correct: A. Variance vs. budget will look worse than reality. Switch to billed cost for variance reporting. Budgets are set against billed amounts. Reporting variance against rack rate over-states spend systematically.
Q3
The “cost_source” label on a daily rollup shows “actual” but a tooltip says “partial: last 2 days fallback to calculated.” How should this be interpreted?
A. The data is unreliable and should simply be ignored until the billing feed has fully caught up with it again
B. The data is best-available; actual where it has landed, calculated as a placeholder where billing sync has not yet caught up
C. Wait for the billing sync
D. The label is wrong
Show answer
Correct: B. The rollup is the right answer for “now.” This is the intended behaviour. The rollup uses the best available source per day. Users get the most up-to-date number; the tooltip is honest about the fallback.
5. Apply
The two-source model is the spine of ZopNight’s cost surface. Visible places:
- Reports header: Cost Source label: “Unblended Cost” or “Rack Rate”
- Reports → Trends: splits each data point into
actualCostUsdandcalculatedCostUsd - Cloud Accounts → Sync Status: per-account billing-sync health
- Recommendations cards: savings claims use the appropriate column (rack rate for avoided hours, billed for projected forward-looking savings)
The model is documented in the USE-CASES.md and FEATURES.md reference. The architectural decision is documented in 00_PLAN.md § Voice & accessibility.
Related lessons
- L5: Currency, FX, and the date-specific exchange rate (next)
- T0.M0.1.L3: Granularity vs. timeliness
- T3.M3.5: Showback design
Glossary terms touched
Two-source cost model · cost_source · COALESCE pattern · Unblended Cost label