Lakehouse patterns

Medallion architecture: bronze, silver, gold explained

The medallion architecture is the default way modern lakehouse teams organize data — three layers of increasing quality, each rebuildable from the one before it. Here's what actually goes in each layer, with real tables.

The one-line definition

Land raw data untouched in Bronze, clean and conform it in Silver, aggregate it for the business in Gold. Every layer is materialized, versioned and reproducible from the layer beneath it.

Bronze — raw, immutable, append-only

Bronze is a faithful copy of the source. No renaming, no casting, no filtering, no deduplication. You add ingestion metadata and nothing else. If your Silver logic has a bug six months from now, Bronze is what lets you rebuild history.

-- bronze.orders_raw
create table bronze.orders_raw (
  payload        variant,        -- the untouched source record
  source_file    string,
  ingested_at    timestamp,
  _batch_id      string
)
partitioned by (date(ingested_at));

Rules of thumb: append-only, schema-on-read, partitioned by ingestion date, and retained long enough to replay any downstream failure.

Silver — cleaned, typed, deduplicated

Silver is where data becomes trustworthy: types are enforced, keys are deduplicated, nulls are handled, and entities from different sources are conformed into one shape. This is the layer analysts and data scientists should be allowed to query.

-- silver.orders
with ranked as (
  select
    payload:order_id::bigint        as order_id,
    payload:customer_id::bigint     as customer_id,
    payload:amount_cents::int / 100.0 as amount_usd,
    payload:status::string          as status,
    payload:ordered_at::timestamp   as ordered_at,
    ingested_at,
    row_number() over (
      partition by payload:order_id::bigint
      order by ingested_at desc
    ) as rn
  from bronze.orders_raw
)
select * exclude (rn)
from ranked
where rn = 1                 -- keep only the latest version of each order
  and order_id is not null;

Silver is also where you attach data quality tests: uniqueness on order_id, not-null on foreign keys, accepted values on status. A failing test here stops Gold from being built on bad data.

Gold — business-ready aggregates

Gold tables answer questions, not store facts. One table per business concept, shaped exactly for a dashboard, a metric, or a feature store. Denormalized on purpose — fast, cheap and obvious to consume.

-- gold.daily_revenue_by_region
select
  date(o.ordered_at)          as order_date,
  c.region,
  count(distinct o.order_id)  as orders,
  sum(o.amount_usd)           as revenue_usd,
  sum(o.amount_usd)
    / nullif(count(distinct o.customer_id), 0) as revenue_per_customer
from silver.orders o
join silver.customers c using (customer_id)
where o.status = 'completed'
group by 1, 2;

How the layers map to the tools you know

  • dbt: sources → staging models → intermediate → marts.
  • Databricks / Delta Lake: literally bronze / silver / gold schemas.
  • Apache Iceberg on S3: same layering, different table format — see our Iceberg guide.
  • Kimball warehousing: staging → conformed dimensions/facts → aggregate marts.

Five mistakes that break medallion pipelines

  • Transforming in Bronze. The moment you clean on ingest, you lose replay.
  • Letting dashboards read Silver. Business logic leaks into BI tools and diverges.
  • One giant Gold table. Gold should be many small, purpose-built tables.
  • No tests between layers. Without contract tests, bad data flows straight to executives.
  • Full refresh everywhere. Silver and Gold should be incremental once volume grows.

Practice it, don't just read it

Reading a diagram won't make you fluent. Build the layers yourself: our dbt course covers staging and marts hands-on, the lakehouse guide covers the storage side, and the architecture deep dives show how Netflix, Uber and Spotify layer their real pipelines.

FAQ

What is the medallion architecture?
The medallion architecture is a lakehouse design pattern that organizes data into three progressively refined layers: Bronze (raw ingested data), Silver (cleaned, conformed, deduplicated) and Gold (business-level aggregates ready for BI and ML). Each layer is a separate set of tables, so you can always rebuild the next layer from the previous one.
Why is it called bronze, silver and gold?
The metals are a quality metaphor — data gets more valuable as it moves through the layers. Databricks popularized the naming, but the same pattern exists elsewhere as raw / staging / marts (dbt) or landing / conformed / presentation (Kimball-era warehousing).
Do I need Databricks to use the medallion architecture?
No. It's a design pattern, not a product. You can implement it on Snowflake, BigQuery, Apache Iceberg on S3, Delta Lake, or even Postgres + dbt. What matters is the layering discipline and the ability to reprocess from Bronze.
Should Bronze data ever be modified?
No. Bronze is append-only and immutable — it's your replay buffer. If a Silver transformation has a bug, you fix the code and rebuild Silver from Bronze. Mutating Bronze destroys that guarantee.
Is the medallion architecture the same as ELT?
They're complementary. ELT describes when transformation happens (after loading, inside the warehouse). Medallion describes how you organize those transformations into layers. Almost every modern ELT stack ends up with some form of medallion layering.
How many layers should I actually have?
Three is the default and works for most teams. Small teams often collapse to two (raw + marts). Large orgs sometimes add an interim layer between Silver and Gold for shared business logic. Don't add layers you can't justify — every layer costs compute and freshness.

Ready to start?

7 days free. Then less than a coffee per month.

Build a medallion pipeline — 7 days free