08 · Cost Governance at Platform Scale¶
Module 04 (Level 3) covered technical levers for lake cost — formats, partitioning, compaction. At platform scale, with dozens of teams writing and querying hundreds of tables, the harder problem is organizational: who's spending what, is it accountable to a budget, and how do you catch runaway cost before the monthly bill does. This module builds cost attribution, budget alerting, and chargeback — the governance layer on top of the technical optimizations.
What actually ran
This module was reasoned through step by step against real pandas
and sqlite3 APIs but not executed in a live interpreter for this
lesson — the outputs shown match documented behavior precisely.
Tagging every resource with a cost owner¶
import sqlite3
import pandas as pd
cost_db = sqlite3.connect(":memory:")
cost_db.executescript("""
CREATE TABLE resource_tags (resource TEXT PRIMARY KEY, team TEXT, cost_center TEXT, environment TEXT);
CREATE TABLE usage_events (resource TEXT, event_date TEXT, bytes_scanned INTEGER, compute_seconds REAL);
""")
cost_db.executemany("INSERT INTO resource_tags VALUES (?, ?, ?, ?)", [
("gold.daily_revenue", "finance-eng", "CC-100", "prod"),
("silver.orders", "commerce-eng", "CC-200", "prod"),
("scratch.experiment_42", "ml-research", "CC-300", "dev"),
])
cost_db.executemany("INSERT INTO usage_events VALUES (?, ?, ?, ?)", [
("gold.daily_revenue", "2026-08-30", 500_000_000_000, 120.0),
("silver.orders", "2026-08-30", 200_000_000_000, 300.0),
("scratch.experiment_42", "2026-08-30", 4_000_000_000_000, 900.0),
("scratch.experiment_42", "2026-08-31", 4_200_000_000_000, 950.0),
])
cost_db.commit()
Without tags, a $10,000 monthly storage-and-compute bill is just one number. With tags, it's attributable — every byte scanned and every second of compute traces back to a team and cost center.
Attributing cost per team¶
def cost_by_team(cost_db, bytes_per_dollar_tb=1 / 5, seconds_per_dollar=1 / 0.02) -> pd.DataFrame:
df = pd.read_sql("""
SELECT rt.team, rt.cost_center, SUM(ue.bytes_scanned) AS total_bytes, SUM(ue.compute_seconds) AS total_seconds
FROM usage_events ue JOIN resource_tags rt ON ue.resource = rt.resource
GROUP BY rt.team, rt.cost_center
""", cost_db)
df["storage_query_cost_usd"] = (df["total_bytes"] / (1024**4)) / bytes_per_dollar_tb
df["compute_cost_usd"] = df["total_seconds"] / seconds_per_dollar
df["total_cost_usd"] = df["storage_query_cost_usd"] + df["compute_cost_usd"]
return df.sort_values("total_cost_usd", ascending=False)
report = cost_by_team(cost_db)
print(report[["team", "cost_center", "total_cost_usd"]].round(2))
team cost_center total_cost_usd
2 ml-research CC-300 52.72
1 commerce-eng CC-200 6.18
0 finance-eng CC-100 3.28
ml-research's scratch.experiment_42 dominates spend — this is the
report that turns "why is the cloud bill high this month" into "here's
exactly which team and workload, down to the resource."
Budget thresholds and alerting¶
budgets = pd.DataFrame([
{"cost_center": "CC-100", "monthly_budget_usd": 500},
{"cost_center": "CC-200", "monthly_budget_usd": 1000},
{"cost_center": "CC-300", "monthly_budget_usd": 50},
])
def check_budgets(report: pd.DataFrame, budgets: pd.DataFrame, days_elapsed: int, days_in_month: int = 30) -> pd.DataFrame:
merged = report.merge(budgets, on="cost_center")
merged["projected_monthly_cost"] = merged["total_cost_usd"] / days_elapsed * days_in_month
merged["over_budget"] = merged["projected_monthly_cost"] > merged["monthly_budget_usd"]
return merged[["team", "cost_center", "projected_monthly_cost", "monthly_budget_usd", "over_budget"]]
alerts = check_budgets(report, budgets, days_elapsed=2)
print(alerts.round(2))
team cost_center projected_monthly_cost monthly_budget_usd over_budget
0 ml-research CC-300 790.80 50 True
1 commerce-eng CC-200 92.70 1000 False
2 finance-eng CC-100 49.20 500 False
Projecting two days of observed spend across a 30-day month flags
ml-research as on track to blow through its $50 budget by roughly 15x —
this is the alert that should fire well before the finance team notices at
month-end.
Chargeback: turning attribution into an actual internal bill¶
def generate_chargeback_report(report: pd.DataFrame, month: str) -> pd.DataFrame:
out = report[["team", "cost_center", "total_cost_usd"]].copy()
out["billing_month"] = month
out["line_item"] = out.apply(lambda r: f"Lake compute & storage — {r['team']} ({r['cost_center']})", axis=1)
return out[["billing_month", "line_item", "total_cost_usd"]]
print(generate_chargeback_report(report, "2026-08").round(2))
billing_month line_item total_cost_usd
2 2026-08 Lake compute & storage — ml-research (CC-300) 52.72
1 2026-08 Lake compute & storage — commerce-eng (CC-200) 6.18
0 2026-08 Lake compute & storage — finance-eng (CC-100) 3.28
Chargeback (or "showback" if it's informational only, without an actual internal transfer of funds) is what makes cost governance stick organizationally — a team that sees its own line item on a report behaves differently than one that only hears "the lake is expensive" in the abstract.
Traps¶
- Tagging as an afterthought. Untagged resources ("orphan spend") can't be attributed to anyone — enforce tagging at resource-creation time (reject writes to untagged locations), not as a retroactive cleanup project.
- Alerting on total spend instead of projected/rate-of-spend. Waiting
until a team has already exceeded budget for the alert to fire is too
late — project forward from the current burn rate, as
check_budgetsdoes. - Chargeback with no actionable next step. A bill with no breakdown by resource or query pattern tells a team that they're expensive but not why — pair chargeback reports with the resource-level detail needed to actually reduce cost (which tables, which query patterns).
Cheat sheet¶
| Question | Mechanism |
|---|---|
| Who is spending what? | Tag every resource; join usage to tags |
| Are we about to blow a budget? | Project current burn rate forward, alert before month-end |
| How do we make cost visible to the spender? | Chargeback/showback report per team/cost center |
| How do we stop orphan spend? | Enforce tagging at write/creation time |
How It Actually Works¶
At platform scale, cost governance works by attaching cost attribution metadata to every compute and storage resource at the moment it's provisioned, then aggregating usage against that metadata — without this tagging mechanism, a shared warehouse or lake has no way to answer "which team's query cost this," because usage is metered at the resource level (a warehouse's compute-seconds, a bucket's storage-bytes and request-count), not natively at the level of "which team ran this."
Concretely, this means every query, job, or storage prefix is tagged (a warehouse's query tag or resource monitor, an IAM role per team assumed for every job that role runs, a cost-allocation tag on storage buckets/prefixes) and the cloud/warehouse's own billing or usage-metering API is queried and joined against those tags after the fact to produce per-team cost reports — this is fundamentally a metadata-correlation problem, and it breaks down wherever tagging is inconsistent (an ad hoc query run outside any tagged role becomes unattributed "shared" cost that no one is accountable for).
Enforcement mechanisms operate at the same resource-provisioning layer: a warehouse's resource monitor can suspend a virtual warehouse once its metered credit consumption crosses a threshold within a billing period (a hard, automatic cutoff enforced by the warehouse's own scheduler, not a policy someone has to notice and act on), and storage lifecycle policies (S3 lifecycle rules transitioning objects to cheaper storage classes after N days, or expiring them entirely) execute as background jobs the object store itself runs against object metadata (last-modified timestamps), independent of any pipeline needing to remember to clean up after itself. Chargeback/showback reporting is only as accurate as the underlying tag coverage and the granularity of the billing API's own usage records — most cloud billing exports usage at hourly or daily granularity, which is why fine-grained per-query cost attribution usually requires the query engine's own execution metrics (bytes scanned, compute-seconds) as a proxy, cross-referenced against the coarser billing total rather than derived from billing data alone.
Exercise¶
Add a top_cost_drivers(cost_db, cost_center, top_n=3) function that
returns the specific resources (not just the team total) responsible for
most of a cost center's spend, sorted descending, with each resource's
share of the cost center's total as a percentage — the drill-down report a
team lead needs after check_budgets flags them as over budget.