System Design · easy

What is the difference between a staging model and a mart in dbt, and why keep them separate?

Asked in Analytics Engineer interviews, in the System Design round.

Short answer

Staging is one-to-one with a source: rename, cast, and clean only — no business logic, no joins. Marts are the joined, business-shaped tables analysts query. Separating them means a source change is absorbed in one place, logic is reusable across marts, and each layer's contract can be tested on its own.

How to answer it

Staging is where the source is made usable; marts are where the business questions are answered. Keeping them apart is what lets either change without breaking the other.

A staging model is one-to-one with a source table. It renames columns to the project's conventions, casts types, trims strings, fixes timezones, and nothing else. No joins, no business logic, no filtering beyond removing obvious junk. It is a view or a light table.

-- stg_shop__orders.sql
select
  id            as order_id,
  customer_id,
  cast(created_at as timestamp) as ordered_at,
  status,
  total_cents / 100.0 as total_amount
from {{ source('shop', 'orders') }}

A mart is the joined, business-shaped table an analyst queries: fct_orders joined to customers and products, dim_customer with segments, a daily revenue rollup. It encodes definitions and is where the business logic lives.

Why separate:

The rule of thumb: if a query needs to know what the source system called a column, it is doing staging's job.

Related questions

Practice this for real