skip to content

Your ELT warehouse bill tripled as models multiplied — how do you decide where transformation belongs?

level: principalimportance: should knowfreq 36%

answer

  1. measure before you re-platform
  2. attribute spend to a model and an owner
  3. often the frequency, not the location
  4. a second engine is a permanent standing cost

basics

~20 s

Attribute spend per model first — a handful usually dominate. Most of the overrun is shape and schedule, not location: full rebuilds that should be incremental, refreshes nobody reads, per-row logic. Move work off the warehouse only where measurement says the pricing genuinely misfits.

solid answer

~50 s

Re-platforming is the most expensive response and usually the wrong first one. Start with attribution: tag transformation runs so spend maps to a model, an owner and a schedule, then rank. The distribution is almost always long-tailed — a small number of jobs carry most of the cost. Classify each of those by *cause*: full refreshes of large tables that should rebuild incrementally, hourly rebuilds feeding a dashboard read weekly, the same expensive intermediate recomputed by ten downstream models, per-row user-defined function work priced badly against set-based execution. Each has a fix that keeps the work in the warehouse. Only after the shape and the frequency are right does location become a real question, and then only for jobs where a measured comparison shows an external engine substantially cheaper — remembering that a second engine costs a permanent team, permission model and on-call rotation, not just its compute. Then close the loop with ownership and showback so the next tripling cannot happen quietly.

go deeper

for a junior

Recall that in an ELT stack every model's rebuild costs warehouse compute, so cost scales with how much data each model scans and how often it runs.

for a middle

Explain the levers that reduce spend without moving work: incremental rebuilds, lower refresh frequency, materialising a shared intermediate once, and layout choices that prune what gets scanned.

for a senior

Show the diagnostic order — attribute spend per model, find the dominant jobs, classify each by cause, fix shape and schedule first — and be able to say when an external engine is genuinely justified by measurement.

for a principal

Own the governance, not just the number. Establish ownership, showback and safe defaults so cost has a feedback loop, and make placement decisions at the granularity of a class of work rather than a single job.

## Why the bill grew ELT converted a fixed, visible transformation budget — a cluster someone procured once — into a variable cost that grows with every model anyone adds. No individual query looks expensive. Each new model is defensible on its own. The total is nobody's specific decision. Tripling is therefore the *expected* outcome of a successful platform with no cost feedback loop, and the interesting question is what changed: more models, more frequent rebuilds, more data per rebuild, or more consumers. Those have different fixes. ## Step one: attribution before architecture You cannot make a placement decision without knowing what is being placed. Tag every transformation run so spend can be attributed to a model, an owner, a schedule and a downstream consumer, and rank the results. Expect a long tail: a handful of jobs typically account for most of the cost, which is good news — it means a small number of decisions can move the number materially. While you are there, capture two facts that are usually missing: **how often each model rebuilds**, and **when its output was last actually read**. Together those find the most embarrassing category of spend — expensive models nobody consumes. ## Step two: classify by cause, not by size For each top consumer, ask *why* it costs what it does. **It rebuilds everything every time.** A model that scans full history nightly to append one day is paying for the whole table daily. Rebuilding only the affected window is usually the single largest saving available, at the price of designing for late-arriving data and periodic full reconciliation. **It rebuilds more often than anyone reads it.** Frequency is a business decision disguised as a technical setting. Hourly refresh of a table feeding a weekly report is pure waste, and dropping to daily is a conversation, not a migration. **It recomputes shared work.** When ten models each derive the same heavy intermediate, materialising that intermediate once and referencing it converts ten expensive scans into one. **Its logic fights the engine.** Row-at-a-time user-defined functions, repeated sorts over huge tables, joins that cannot prune. These are optimisation problems inside the warehouse before they are placement problems. **It scans more than it needs.** Layout choices — partitioning, clustering, pruning-friendly filters — often cut scanned volume dramatically with no change to the logic at all. Only one of these categories argues for leaving the warehouse. The others are shape and schedule. ## Step three: the placement decision, made honestly When a job survives all that and still looks structurally mispriced — heavy per-row work, unstructured parsing, model inference — compare properly: - Run the job both ways on real data and compare **total** cost, including the read-out and write-back, not just the engine's compute charge. - Add the standing cost of the alternative: cluster idle time, a second permission model, a second deployment path, a second on-call rotation, and the engineering time to keep them aligned. This is paid every week regardless of how many jobs use it. - Ask whether the resulting lineage gap is acceptable and how the orchestrator will hold the dependency across it. - Ask who maintains it after its author changes team. A job outside the mainstream path is the first thing to rot. Moving three jobs rarely justifies an engine. Moving a whole class of work — all feature generation, all raw file parsing — sometimes does, and that is the granularity at which the decision should be made. ## Step four: make the fix durable Without a feedback loop the bill regrows, because the mechanism that produced it is untouched. - **Ownership.** Every model has a named owner; unowned models are candidates for deletion, and deletion is the cheapest optimisation there is. - **Showback.** Teams see their own transformation spend on a regular cadence. Visibility alone reliably changes behaviour. - **Guardrails.** Defaults that fail safe: incremental unless justified, a default schedule that is not the fastest one available, alerts on individual jobs whose cost jumps. - **Review at introduction.** New models declare consumer, freshness requirement and expected cost. Refresh frequency should be justified by a stated requirement rather than chosen by habit. - **Retention.** Raw retention policy and intermediate cleanup, decided deliberately rather than accumulating. ## What to resist Resist re-platforming on the strength of a bill alone — the same badly shaped jobs cost badly on any engine, and you will have paid a migration to find out. Resist a blanket refresh-frequency cut that quietly breaks a freshness commitment someone depends on. Resist optimising the long tail; it is where effort goes to die. And resist the framing that this is a technology failure. It is a governance gap, and the durable fix is that transformation cost has an owner, a number and a review — after which "where does transformation belong" becomes answerable per workload instead of as an architecture-wide referendum.

  • Which single change most often cuts an ELT bill without moving any work?
    Rebuilding large models incrementally instead of fully. A model that scans full history nightly to add one day pays for the entire table every night; restricting the rebuild to the affected window scales cost with new data rather than accumulated data. The price is designing for late-arriving rows and scheduling periodic full reconciliation to catch drift.
  • How do you decide a model should simply be deleted?
    Look at last-read time alongside cost. A model that rebuilds on a schedule and has not been queried by a human or a downstream dependency in months is pure spend. Announce a deprecation window, stop the schedule, keep the definition in version control, and drop it if nobody objects — deletion is the cheapest optimisation available.
  • Why is showback effective when engineering mandates often are not?
    Because the cost was invisible, not disputed. Individual queries look cheap and each new model is locally defensible, so the total is nobody's decision. Putting a team's own transformation spend in front of them on a regular cadence restores the feedback loop the fixed cluster used to provide, and behaviour changes without a central team policing every model.

saying these in an interview costs you the question

  • Proposes migrating engines before measuring anything
  • Cuts refresh frequency across the board without checking consumers
  • Compares engine compute prices while ignoring transfer and upkeep
  • Optimises the long tail instead of the dominant jobs
  • Treats a cost overrun as purely technical, not governance

context