See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed ยท Editable canvas, not a picture
The short answer
Medallion architecture organizes a data lake or lakehouse into three progressively refined layers, named bronze, silver, and gold. Bronze holds raw ingested data exactly as it arrived, append-only, with source metadata and ingestion timestamps, so any downstream mistake can be replayed from it. Silver holds cleaned and conformed data: types cast, duplicates removed, keys resolved, late-arriving records handled, one row per business entity per event. Gold holds business-level aggregates and the dimensional models that BI tools and ML features read, shaped for a specific consumption pattern rather than for generality. In practice the layers are schemas, so a table exists three times under three names: bronze.shopify_orders, silver.orders, gold.fact_orders. The pattern comes from Databricks and is the default on Delta Lake, but nothing in it is Databricks-specific: the same three layers work on Snowflake, BigQuery, or Iceberg tables on S3, and in a dbt project they are sources, staging plus intermediate models, and marts. The point of the split is blast radius. A bad transform only ever costs you a rebuild of the layer below, because bronze was never mutated.
1. What is medallion architecture?
Medallion architecture is a data design pattern that organizes your lakehouse into three progressive layers: bronze (raw), silver (cleaned), and gold (business-ready). Each layer improves data quality and moves closer to business value. The medal names carry the ordering and nothing else: a bronze table is not lower quality by accident, it is raw on purpose.
The pattern assumes a lakehouse underneath it: one storage layer, open table formats, and engines reading the same files. If that part is not settled yet, the data lakehouse architecture guide covers the storage and table format decisions that bronze, silver and gold sit on top of. Teams coming from a classic warehouse usually compare both against the data warehouse design guide before committing.
The Core Idea
Bronze
Raw, as-is
Silver
Cleaned, conformed
Gold
Business-ready
Why not just clean the data once?
Because requirements change. Keeping raw data in bronze means you can always reprocess when business logic evolves. Teams that skip bronze often find themselves re-ingesting from source systems when a stakeholder asks for "the data before we applied that filter."
When to use medallion architecture:
Multiple Data Sources
When you're ingesting from 10+ sources with different formats, schemas, and quality levels.
Different Consumers
When data scientists need raw data, analysts need clean data, and dashboards need aggregates.
Evolving Requirements
When business logic changes frequently and you need the ability to reprocess historical data.
Compliance Needs
When you need audit trails, data lineage, and the ability to prove what data looked like at any point.
From experience
Medallion isn't about the name: it's about the principle: don't lose raw data, improve quality progressively, and serve the right abstraction to the right consumer. You can call your layers "raw/staging/marts" or "landing/curated/consumption", the pattern is what matters.
2. Bronze vs silver vs gold: what goes in each layer
The shortest way to tell the three apart is by the question each one answers. Bronze answers what arrived, byte for byte, with no opinion about whether it is correct. Silver answers what is true: one row per business entity, types resolved, duplicates gone, keys joined across sources. Gold answers what the business asked, in the shape of a specific dashboard, metric or model. Each layer has its own purpose, owner, quality bar and access rules.
| Layer | Purpose | Quality Bar | Consumers | Example table |
|---|---|---|---|---|
| ๐ฅ Bronze | Land raw data exactly as received | None: keep everything | Data engineers, debugging | bronze.shopify_orders |
| ๐ฅ Silver | Clean, dedupe, conform schemas | Validated, typed, consistent | Data scientists, advanced analysts | silver.orders |
| ๐ฅ Gold | Business aggregates and metrics | Business-approved, documented | Dashboards, reports, applications | gold.fact_orders |
Key principles for each transition:
Bronze to Silver
Clean and Conform
Deduplicate records, cast data types, apply schema enforcement, filter invalid records, standardize formats (dates, currencies, codes).
Silver to Gold
Aggregate and Enrich
Join related tables, calculate business metrics, apply business logic, create dimensional models, optimize for query patterns.
Each transition is a pipeline job in its own right. Sketching both hops as a data pipeline diagram before writing code surfaces grain mismatches and missing dedup keys while they are still cheap to fix.
Pro Tip
Don't skip silver
It's tempting to go straight from bronze to gold, but silver is where data quality lives. Without it, you end up with duplicated cleaning logic in every gold table, making changes painful and error-prone.
3. What the bronze layer is for
Bronze exists to be a replayable record of what each source system sent. It is your "data lake" in the truest sense: everything lands here, exactly as it arrived. The goal is durability and traceability, not cleanliness. If you can drop every silver and gold table and rebuild the platform from bronze alone, bronze is doing its job.
Bronze should have
- โข Raw data exactly as received (JSON, CSV, Parquet)
- โข Ingestion metadata (timestamp, source, batch ID)
- โข Append-only writes (never update or delete)
- โข Partitioned by ingestion date
- โข Long retention (months to years)
Bronze should NOT have
- โข Schema enforcement (let bad data in)
- โข Data transformations
- โข Deduplication logic
- โข Business logic or calculations
- โข Access by business users
Bronze table structure:
Example: Bronze orders table schema
-- Bronze: raw_orders CREATE TABLE bronze.raw_orders ( -- Ingestion metadata _ingested_at TIMESTAMP, _source_file STRING, _batch_id STRING, -- Raw payload (store as-is) raw_payload STRING, -- JSON string, unparsed -- Or if structured: order_id STRING, -- Not validated yet customer_id STRING, order_date STRING, -- Could be any format amount STRING, -- Could have currency symbols status STRING ) PARTITIONED BY (_ingested_at::DATE)
Add ingestion metadata to every record
Timestamp, source file, batch ID. You will need this for debugging and reprocessing.
Use append-only writes
Never UPDATE or DELETE in bronze. If you receive a correction, it is a new record with a new ingestion timestamp.
Partition by ingestion date
Makes it easy to reprocess specific time ranges and manage retention.
Keep it cheap
Use compressed formats (Parquet, ORC) and cold storage tiers for older partitions.
The one exception to append-only
Deletion requests under GDPR or CCPA have to reach bronze too, since bronze holds the full history. Handle them as targeted deletes keyed on the subject identifier, logged separately, rather than by relaxing the append-only rule for pipeline code. Delta Lake, Iceberg and Hudi all support row-level deletes for exactly this case.
4. What the silver layer is for
Silver is where the real work happens. This is your "single source of truth" for cleaned, validated, entity-level data. Think of it as enterprise-grade data. And if upstream teams keep breaking your silver models with surprise schema changes, formalize the expectations as data contracts rather than patching the cleanup logic every sprint.
Silver layer responsibilities:
Schema Enforcement
Cast types, enforce NOT NULL, validate formats. Bad records go to a quarantine table.
Deduplication
Remove duplicate records. Use business keys + timestamp to keep the latest version.
Standardization
Normalize dates to ISO format, currencies to base, codes to standard values.
Data Quality Checks
Run automated tests: null rates, uniqueness, referential integrity, value ranges.
Example: Silver orders transformation (dbt)
-- models/silver/orders.sql
WITH source AS (
SELECT * FROM {{ source('bronze', 'raw_orders') }}
WHERE _ingested_at >= CURRENT_DATE - INTERVAL '7 days'
),
deduplicated AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY order_id
ORDER BY _ingested_at DESC
) as row_num
FROM source
),
cleaned AS (
SELECT
-- Cast and validate types
CAST(order_id AS BIGINT) AS order_id,
CAST(customer_id AS BIGINT) AS customer_id,
-- Standardize date format
TO_DATE(order_date, 'YYYY-MM-DD') AS order_date,
-- Clean amount (remove currency symbols)
CAST(REGEXP_REPLACE(amount, '[^0-9.]', '') AS DECIMAL(10,2)) AS amount,
-- Normalize status to uppercase
UPPER(TRIM(status)) AS status,
-- Keep lineage
_ingested_at,
_batch_id
FROM deduplicated
WHERE row_num = 1
AND order_id IS NOT NULL
)
SELECT * FROM cleanedTwo details in that model are the ones teams get wrong. The dedup window is a rolling seven days rather than the current batch, because a source that resends yesterday with a correction has to overwrite yesterday, not sit next to it. And the ingestion metadata survives into silver, which is what lets you trace a wrong number in a dashboard back to the file it came from. Keeping those columns is the cheapest lineage you will ever have.
From experience
Silver is where most teams underinvest. They rush to build gold tables and end up duplicating cleaning logic everywhere. Spend time getting silver right: it pays dividends in every downstream model.
5. What the gold layer is for
Gold is where business value lives. These are the tables your stakeholders actually query. Think dimensional models, metrics, and use-case-specific aggregates. A gold table is allowed to be redundant with another gold table, because each one is shaped for its consumer rather than for generality.
Common gold layer patterns:
Dimensional Models (Star Schema)
Fact tables (events, transactions) surrounded by dimension tables (customers, products, time). Optimized for BI tools and ad-hoc queries. Our star schema guide covers the full Kimball design method, and medallion vs dimensional modeling covers why the two are not alternatives.
Example:
fact_orders with dim_customers, dim_products, dim_datePre-Aggregated Metrics
Daily/weekly/monthly rollups that power dashboards. Faster queries, lower compute costs.
Example:
daily_revenue_by_region, weekly_active_users, monthly_churn_ratesFeature Tables (ML)
Pre-computed features for machine learning models. Point-in-time correct, versioned.
Example:
customer_features, product_embeddings, user_activity_signalsExample: Gold fact table (dbt)
-- models/gold/fact_orders.sql
WITH orders AS (
SELECT * FROM {{ ref('silver_orders') }}
),
customers AS (
SELECT * FROM {{ ref('dim_customers') }}
),
products AS (
SELECT * FROM {{ ref('dim_products') }}
)
SELECT
-- Surrogate key
{{ dbt_utils.generate_surrogate_key(['o.order_id']) }} AS order_key,
-- Foreign keys to dimensions
c.customer_key,
p.product_key,
d.date_key,
-- Degenerate dimensions
o.order_id,
o.status,
-- Measures
o.quantity,
o.unit_price,
o.quantity * o.unit_price AS line_total,
o.discount_amount,
-- Audit columns
o._ingested_at AS source_loaded_at,
CURRENT_TIMESTAMP AS dbt_loaded_at
FROM orders o
LEFT JOIN customers c ON o.customer_id = c.customer_id
LEFT JOIN products p ON o.product_id = p.product_id
LEFT JOIN {{ ref('dim_date') }} d ON o.order_date = d.date_dayGold principle
Optimize for queries
Partition by common filter columns (date, region). Cluster by join keys.
Gold principle
Document business logic
Every gold table should have clear definitions of what metrics mean.
Gold principle
Version carefully
Changes to gold can break dashboards. Use semantic versioning or aliases.
6. Medallion architecture naming conventions
The rule that makes everything else easier: the layer goes in the schema, the entity goes in the table, and the environment goes in the catalog or database. That gives you names like prod.silver.orders and dev.silver.orders, so the same SQL runs in both, and it lets you grant permissions on a whole layer in one statement instead of enumerating tables.
| Layer | Name pattern | Example | Why |
|---|---|---|---|
| Bronze | bronze.<source>_<object> | bronze.shopify_orders | Two systems both have "orders". The source prefix is what keeps them apart. |
| Silver | silver.<entity> | silver.orders | Silver is where sources merge, so the source name is dropped on purpose. |
| Gold | gold.dim_ / fact_ / agg_ | gold.agg_sales_daily_by_region | The prefix carries the role, the suffix carries the grain. |
| Quarantine | <layer>.<table>_quarantine | silver.orders_quarantine | Named after its target, so a failed load is one table away from its cause. |
The rules worth writing down:
Keep the entity name identical across layers
orders stays orders from bronze.shopify_orders to silver.orders to gold.fact_orders. A rename mid-pipeline is the single most common reason lineage becomes unreadable.
Prefix technical columns with an underscore
_ingested_at, _source_file, _batch_id. They sort together, they are obviously not business columns, and they can be dropped in one SELECT * EXCEPT clause when a table is exposed.
Never put the layer in the table name
silver_orders inside a schema already called silver reads as silver.silver_orders. It also breaks the moment you clone the schema to test a change.
State the grain in aggregate names
agg_sales_daily_by_region says what one row is. agg_sales does not, and someone will eventually join it wrong.
Do not version with suffixes
fact_orders_v2 becomes permanent and both versions stay in production. Version behind a view or an alias and keep one canonical name.
Pick singular or plural once
Either dim_customer and fact_order, or dim_customers and fact_orders. The choice does not matter, the inconsistency does.
Folder and database structure:
# Typical naming convention
catalog/
โโโ bronze/
โ โโโ raw_orders
โ โโโ raw_customers
โ โโโ raw_products
โ โโโ raw_events
โโโ silver/
โ โโโ orders # Cleaned orders
โ โโโ customers # Cleaned customers
โ โโโ products # Cleaned products
โ โโโ events # Cleaned events
โโโ gold/
โ โโโ dim_customers # Dimension: customers
โ โโโ dim_products # Dimension: products
โ โโโ dim_date # Dimension: date
โ โโโ fact_orders # Fact: orders
โ โโโ agg_daily_sales # Aggregate: daily sales
โโโ quarantine/
โโโ orders_failed # Records that failed validation
โโโ events_failedPro Tip
Use separate schemas, not prefixes
Don't just use prefixes (raw_, silver_, gold_). Use separate databases or schemas so you can apply different access controls, storage policies, and retention rules to each layer. The wider question of where the environment name goes is covered in the warehouse naming conventions guide.
7. What the Databricks documentation says about bronze, silver and gold
Databricks coined the term and publishes the definition in two places: a glossary entry on databricks.com and the lakehouse architecture section of the product documentation. The definition itself is deliberately short. Medallion architecture is described as a data design pattern used to logically organize data in a lakehouse, with the goal of incrementally and progressively improving the structure and quality of the data as it flows through bronze, then silver, then gold. Everything past that sentence in the docs is guidance rather than rule, which is why implementations differ so widely and still call themselves medallion.
On bronze
Data lands as-is from the source system, typically append-only, with metadata columns added at ingestion time such as the load timestamp and the source file name. The docs treat bronze as the record of what arrived and the point you reprocess from, not as a place to fix anything.
On silver
Records are matched, merged, conformed and cleansed so the layer provides an enterprise view of the key business entities. The docs describe silver as more normalized than gold, closer to a 3NF or Data Vault style model, and as the layer data scientists and advanced analysts read directly.
On gold
Gold is consumption-ready, project-specific and read-optimized, usually denormalized, powering BI dashboards, ML features and applications. The docs are explicit that medallion does not replace dimensional modeling: star schemas and Kimball-style models are what gold normally contains.
Two things the docs say that summaries leave out
First, the layer names are a convention and not a requirement: a platform with raw, curated and consumption schemas is the same pattern. Second, three is not a fixed number. Adding a landing zone before bronze, or splitting gold per consuming domain, is treated as a normal variation rather than a deviation.
On Databricks specifically, the pieces that carry the pattern are Unity Catalog for the three-level catalog.schema.table namespace, Auto Loader for incremental file ingestion into bronze, and Delta Lake MERGE or streaming tables for the two hops. Because Unity Catalog has three levels, the layer can live either at the catalog level or at the schema level, and both layouts appear in the Databricks examples. The Unity Catalog structure guide walks through that decision, and the Databricks platform diagram guide covers documenting the result.
From experience
The most common misreading of the docs is treating "silver is more normalized" as an instruction to build a full Data Vault. Silver has to be normalized enough that a business entity exists once and is joinable. Going further than that is a modeling decision with its own cost, not something medallion asks of you.
8. Bronze, silver and gold on Snowflake, BigQuery and open lakehouses
Medallion works on any modern data platform. None of them except Databricks has a native notion of layers, which is good news: the layers are just containers you create, and every platform gives you a way to secure and bill them separately.
| Platform | Bronze | Silver/Gold | Format |
|---|---|---|---|
| Databricks | Unity Catalog | Delta Lake + dbt | Delta |
| Snowflake | RAW database | dbt + Snowflake | Native tables |
| BigQuery | raw_ dataset | dbt + BQ | Native tables |
| AWS (Open) | S3 + Glue | Spark + dbt | Iceberg/Hudi |
Snowflake
Two layouts are common: three databases (RAW, SILVER, GOLD) when you want separate storage grants and separate cost attribution, or one database with three schemas when cross-layer queries are frequent. Bronze is usually loaded by Snowpipe or an EL tool into a table with a VARIANT column, which keeps the JSON payload intact and still queryable, so you get bronze fidelity without giving up SQL access. The hops are built with streams and tasks, or with dynamic tables when you would rather declare the target state than orchestrate it. One warning worth repeating: Time Travel is not bronze. Its retention tops out at 90 days on the higher editions and one day on Standard, so it covers a bad deploy last Tuesday, not a reprocessing request for last year. The Snowflake architecture guide covers warehouse sizing per layer.
BigQuery
Layers are datasets, and the dataset is also the unit of location and access control, so one dataset per layer per region falls out naturally. Bronze commonly uses ingestion-time partitioning so a reprocessing job can target the exact load window, and external tables over Cloud Storage let you keep untouched files as a landing zone in front of bronze without loading them twice. Gold is where partitioning and clustering earn their keep, since BigQuery bills the bytes each dashboard query scans.
Open lakehouse on object storage
With Iceberg, Hudi or Delta on S3, GCS or ADLS, the layers are prefixes plus catalog namespaces, and a catalog (Glue, Nessie, Polaris or another REST catalog) is what makes them tables rather than folders. The pattern to avoid is bronze as loose Parquet with no table format, because you lose atomic writes and schema evolution exactly where late and malformed data arrives.
Cost note
Bronze is the layer that grows without bound and the one nobody queries. Give it a lifecycle rule from day one: compressed columnar files, older partitions on an infrequent-access or archive tier, and a stated retention in the same document as the schema. Teams that skip this discover the problem as a bill rather than as a decision.
9. Medallion architecture in dbt: staging, intermediate and marts
dbt has its own three-part convention (staging, intermediate, marts) and it maps onto medallion cleanly once you accept one thing: dbt does not build bronze. An ingestion tool such as Fivetran, Airbyte, Auto Loader or Snowpipe lands bronze, and dbt declares it as a source. Everything dbt builds starts at silver.
| Medallion layer | dbt equivalent | Typical materialization |
|---|---|---|
| Bronze | Sources declared in a .yml file, not models | Loaded by the EL tool |
| Silver (first half) | models/staging, one stg_ model per source table | View |
| Silver (second half) | models/intermediate, joins, dedup, conformed entities | Ephemeral or table |
| Gold | models/marts, dim_, fct_ and aggregates | Table or incremental |
Bronze as a dbt source, with freshness
# models/staging/_sources.yml
sources:
- name: bronze
schema: bronze
loaded_at_field: _ingested_at
freshness:
warn_after: {count: 12, period: hour}
error_after: {count: 24, period: hour}
tables:
- name: raw_orders
- name: raw_customersOne schema per layer, set once in dbt_project.yml
# dbt_project.yml
models:
my_platform:
staging:
+schema: silver
+materialized: view
intermediate:
+schema: silver
+materialized: ephemeral
marts:
+schema: gold
+materialized: tableOne gotcha with that config: by default dbt builds a custom schema name by concatenating the target schema and the value you set, so +schema: gold produces analytics_gold rather than gold. If you want the layer names bare, override the generate_schema_name macro in your project. It is a ten-line macro and it is the standard first customization of a medallion dbt project.
Put the tests at the silver boundary
unique, not_null, relationships and accepted_values belong on the staging and intermediate models. A test on a mart tells you something broke; a test on silver tells you where.
Use snapshots between silver and gold
dbt snapshots are how a silver entity becomes a slowly changing dimension in gold. Snapshotting bronze instead is a common mistake: you snapshot noise, including duplicate resends.
Let source freshness watch bronze
dbt source freshness on _ingested_at is the cheapest possible check that ingestion is still running, and it fails before the pipeline builds stale gold tables on top.
The rest of the project conventions, folder layout, model contracts and CI, are in the dbt best practices guide.
10. How to draw a medallion architecture diagram
A medallion diagram is read by two audiences: an engineer who needs to know which job writes which table, and a stakeholder who needs to know where a number comes from. One picture can serve both if it follows four rules.
Three zones, left to right
Bronze, silver and gold as labeled containers, sources outside on the left, consumers outside on the right. The zone boundary is the part that carries the meaning, so it should be the strongest line in the drawing.
One node per table group, not per table
A platform with 200 tables becomes unreadable at 200 boxes. Group bronze and silver by source system, and gold by mart. If a node needs a number, put the table count in its label.
Label edges with the job, not the verb
Auto Loader, dbt run --select marts, MERGE INTO, Snowpipe. A reader who can name the job can go find it. An edge labeled "transform" tells nobody anything.
Show the grain change at each hop
One event per row, one order per row, one region per day. Grain is where medallion diagrams usually hide the bug, because a silver to gold hop that changes grain silently is exactly how a metric gets double counted.
This is the part Datadef was built for. Describe the platform in a sentence, naming the sources, the engine and the marts, and it draws the three layers as labeled zones with the real Databricks, Snowflake, dbt, Fivetran, Airflow and Kafka icons rather than generic boxes, then leaves it on a canvas you can edit. Zone names in the request are treated as a specification, so asking for one zone per medallion layer gives you exactly that. The result can be published as a live embed in a README, Notion page or Confluence page, where the image follows the canvas instead of being a screenshot that ages. The prompter at the top of this page is already seeded with a medallion lakehouse, and the medallion generator is the same thing with a blank description.
For the wider question of keeping a lakehouse diagram accurate over time rather than drawing it once, see how to document a lakehouse.
11. Medallion architecture best practices
Never delete from bronze
Append-only writes. If you need to correct data, add a new record. Bronze is your audit trail.
Invest heavily in silver
This is where data quality lives. Get deduplication, schema enforcement, and standardization right.
Keep gold simple
Gold tables should be easy to query. Pre-join, pre-aggregate, optimize for the consumer.
Document everything in gold
Every gold table needs: owner, description, column definitions, refresh schedule, SLA.
Use incremental processing
Process only new/changed data. Full refreshes are expensive and slow at scale.
Quarantine bad records
Don't drop bad data silently. Route it to a quarantine table for investigation.
Test at every layer
Data quality checks at bronze to silver (schema), silver to gold (business rules), and on gold metrics themselves.
Apply access controls by layer
Bronze: data engineers only. Silver: data team. Gold: business users and dashboards.
The checks that belong at each boundary, and what to alert on rather than log, are in the data quality best practices guide.
From experience
The teams that struggle with medallion usually have one problem: they treat it as a one-time migration instead of an ongoing architecture. Each layer needs ownership, maintenance, and continuous improvement.
12. Frequently asked questions
What is medallion architecture?
Medallion architecture organizes a lakehouse into three progressively refined layers. Bronze holds raw ingested data exactly as it arrived, silver holds cleaned and conformed entity tables, and gold holds the aggregates and dimensional models that BI tools and ML features read. Data quality improves at each hop, and because bronze is never mutated, a downstream mistake is fixed by rebuilding from it rather than by re-ingesting from the source.
What is the difference between bronze, silver, and gold layers?
Bronze is raw and append-only, usually untyped, with ingestion metadata attached and no validation. Silver is typed, deduplicated and conformed, one row per business entity, with quality tests at the boundary. Gold is shaped for a consumer rather than for generality: fact and dimension tables, pre-aggregated metrics, ML feature tables. Bronze answers what arrived, silver answers what is true, gold answers what the business asked.
In medallion architecture, what is the bronze layer specifically intended for?
Bronze is intended to be a faithful, replayable record of what each source system sent. It stores data exactly as received, append-only, partitioned by ingestion date, with metadata columns such as ingestion timestamp, source file and batch id. It applies no schema enforcement, no deduplication and no business logic, so a change in downstream logic can be reprocessed without going back to the source system.
What do the Databricks docs say about bronze, silver, and gold?
Databricks defines the medallion architecture as a data design pattern that logically organizes data in a lakehouse and incrementally improves its structure and quality from bronze through silver to gold. The docs describe bronze as ingested as-is with added metadata, silver as matched, merged, conformed and cleansed into an enterprise view of key business entities, and gold as consumption-ready, read-optimized and project-specific. Layer names and counts are presented as conventions, not rules.
What is the naming convention for medallion architecture tables?
Put the layer in the schema and the entity in the table: bronze.shopify_orders, silver.orders, gold.fact_orders. Keep the source system in bronze names and drop it in silver, where sources merge into one conformed entity. Prefix gold tables with dim_, fact_ or agg_ and state the grain, as in agg_sales_daily_by_region. Put the environment in the catalog or database, never in the table name, so the same SQL runs in dev and prod.
How does medallion architecture map to dbt?
Bronze is not built by dbt. An ingestion tool lands it and dbt declares it as a source in a sources.yml file. dbt staging models do the one-to-one casting and renaming, intermediate models do the joins and deduplication, and together they form silver. Marts are gold: dim_, fct_ and aggregate tables. Set the schema per folder in dbt_project.yml so each layer lands in its own schema.
Can you use medallion architecture on Snowflake?
Yes. Snowflake has no built-in notion of layers, so teams create either three databases (RAW, SILVER, GOLD) or one database with three schemas. Snowpipe or an EL tool loads bronze, often into a VARIANT column that keeps the payload intact, and streams and tasks or dynamic tables build the incremental hops. Time Travel is not a substitute for bronze, because its retention is capped at 90 days on the higher editions and one day on Standard.
Is raw the same thing as bronze, or is it a fourth layer?
In most implementations raw and bronze are the same layer, and the two words are used interchangeably. Some teams keep a separate landing zone of untouched source files on object storage, then load those files into bronze tables that add ingestion metadata. That four-zone variant is worth the extra hop when the source format is not queryable, or when retention policy applies to files rather than tables.
How is medallion architecture different from staging, ODS and data marts in a classic warehouse?
The mapping is close. Staging matches bronze, an operational data store or integration layer matches silver, and data marts match gold. The two real differences are that bronze keeps full history instead of being truncated after each load, and that all three layers live in the same storage and table format, so a consumer can read across layers without moving a copy anywhere.
Is medallion architecture only for Databricks?
No. Databricks named and popularized the pattern and it is the default on Delta Lake, but nothing in it depends on Databricks. The same three layers work on Snowflake, BigQuery, Redshift, or Iceberg and Hudi tables on object storage. What the platform has to provide is cheap storage for bronze, an engine for the two transform hops, and access control granular enough to differ per layer.
Can you skip the silver layer and go straight from bronze to gold?
You can, and small platforms with a single source often do. The cost appears on the third gold table, when the same casting, deduplication and key resolution has been copied three times and two copies have quietly drifted. Skip silver only while one team owns every gold table, and expect to add it as soon as a second consumer needs the same cleaned entity.
When should I use medallion architecture?
Use it when several sources feed the same tables, when consumers need different levels of refinement, when business logic changes often enough that reprocessing history matters, or when you have to prove what the data looked like on a given day. A single source feeding one dashboard does not need three layers, and adding them costs storage and orchestration for no return.
Draw your medallion architecture
Describe your bronze, silver and gold layers in one sentence and get an editable diagram with the real platform icons, ready to embed in the README that documents it.
Related Guides
Medallion vs Dimensional Modeling
Why the two are layers of the same platform, not alternatives
Dimensional Modeling Guide
Star schema and Kimball method for the gold layer
Unity Catalog Structure
Catalogs, schemas and where the medallion layers go
dbt Best Practices
Staging, intermediate and marts conventions in practice
Data Quality Best Practices
Catch data issues before stakeholders do
Medallion Architecture Generator
Generate your own bronze/silver/gold diagram from one prompt