ETL and Data Pipelines · Scale, Cost and Privacy

Controlling Pipeline Cost

Why the warehouse bill grew faster than the data, and how incremental processing, right-sized schedules and cost attribution keep pipelines affordable.

Scenario

Example company: all 120 dbt models are materialised as full tables and the whole project runs every hour "so data is fresh". Most models rebuild three years of history each time.

What you see in production

  • Warehouse spend grows 15% a month while data grows 3% a month.
  • The hourly run takes 50 minutes, so runs nearly overlap and queue behind each other.
  • Nobody knows which models or teams drive the cost.

The naive code

# every model, every hour
models:
  +materialized: table
schedule: "0 * * * *"

Reproduce it

The model estimates monthly compute for one large fact table under different strategies.

Full refresh hourly vs incremental on a needed scheduleTry it yourself
history_days = 3 * 365
cost_per_day_processed = 0.02        # compute cost to process one day of data
lookback_days = 3                     # incremental runs reprocess recent days for late data

def monthly(runs_per_day, days_per_run):
    return runs_per_day * 30 * days_per_run * cost_per_day_processed

plans = {
    "full refresh, hourly":          monthly(24, history_days),
    "full refresh, daily":           monthly(1, history_days),
    "incremental (3-day lookback), hourly": monthly(24, lookback_days),
    "incremental (3-day lookback), daily":  monthly(1, lookback_days),
}
for name, cost in plans.items():
    print(f"{name:<38} {cost:>9.2f} per month")

Output

full refresh, hourly                    15768.00 per month
full refresh, daily                       657.00 per month
incremental (3-day lookback), hourly       43.20 per month
incremental (3-day lookback), daily         1.80 per month

Root cause

Every run reprocessed all history, at a frequency nobody needed. Cost scales with data processed × runs, so both factors multiplied.

The fix

  • Make large models incremental: process only new or changed partitions plus a lookback window for late data, using merge or partition overwrite (dbt incremental models). Schedule occasional full refreshes to catch drift.
  • Schedule by need: run each model at the frequency its freshness target requires (see the batch-vs-streaming lesson). Hourly finance tables are rarely needed.
  • Use views for cheap, rarely queried transformations and tables for heavily queried ones.
  • Right-size compute: separate warehouses or queues for ETL and BI, auto-suspend idle compute, and set budgets and alerts.
  • Attribute cost: tag queries with model, pipeline and team, and review the top spenders each month.

Trade-offs

  • Incremental logic is more complex and can drift from a full rebuild; test it and full-refresh periodically.
  • Less frequent runs mean staler data; agree targets with consumers first.

Detect it in production

  • Cost per model or pipeline per day, with alerts on sudden jumps.
  • Ratio of rows processed to rows changed: a high ratio means a model should be incremental.

Key points

  • Cost ≈ data processed × run frequency; reduce both.
  • Use incremental models with a lookback, plus periodic full refreshes.
  • Schedule by freshness need, separate workloads, and attribute cost to owners.

Practice questions

How do incremental models reduce warehouse cost?

Answer

They process only new or changed data (plus a lookback for late arrivals) instead of rebuilding all history on every run, so compute scales with the change volume rather than the table size.

How would you find out which pipelines drive warehouse cost?

Answer

Tag queries with model, pipeline and team (query tags, labels or comments), aggregate the warehouse's query history or billing export by tag, and review the top spenders and their run frequency.

When is a full refresh still useful for an incremental model?

Answer

Periodically, and after logic changes or schema changes, to rebuild from source and remove drift that incremental merges can accumulate.

Open in the app to mark lessons complete, take notes and track your progress.