Data Platform Guide

Medallion Architecture

Bronze, Silver, Gold—the pattern that lets you ingest messy data fast, clean it progressively, and serve business-ready datasets. This guide shows you how to implement Medallion Architecture without over-engineering it.

22 min readFor Data & Platform EngineersCode examples included

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

119/20003 credits left
Try:

No account needed · Editable canvas, not a picture

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 Core Idea

Bronze

Raw, as-is

Silver

Cleaned, conformed

Gold

Business-ready

Why Not Just Clean 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. The Three Layers Explained

Each layer has a specific purpose, owner, and quality bar. Here's the mental model that makes Medallion work.

LayerPurposeQuality BarConsumers
🥉 BronzeLand raw data exactly as receivedNone—keep everythingData engineers, debugging
🥈 SilverClean, dedupe, conform schemasValidated, typed, consistentData scientists, advanced analysts
🥇 GoldBusiness aggregates and metricsBusiness-approved, documentedDashboards, reports, applications

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.

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. Bronze Layer Deep Dive

Bronze is your "data lake" in the truest sense: everything lands here, exactly as it arrived. The goal is durability and traceability, not cleanliness.

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.

4. Silver Layer Deep Dive

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.

Silver layer responsibilities:

1

Schema Enforcement

Cast types, enforce NOT NULL, validate formats. Bad records go to a quarantine table.

2

Deduplication

Remove duplicate records. Use business keys + timestamp to keep the latest version.

3

Standardization

Normalize dates to ISO format, currencies to base, codes to standard values.

4

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 cleaned

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. Gold Layer Deep Dive

Gold is where business value lives. These are the tables your stakeholders actually query. Think dimensional models, metrics, and use-case-specific aggregates.

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.

Example:

fact_orders ← dim_customers, dim_products, dim_date

Pre-Aggregated Metrics

Daily/weekly/monthly rollups that power dashboards. Faster queries, lower compute costs.

Example:

daily_revenue_by_region, weekly_active_users, monthly_churn_rates

Feature Tables (ML)

Pre-computed features for machine learning models. Point-in-time correct, versioned.

Example:

customer_features, product_embeddings, user_activity_signals

Example: 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_day

Gold 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. Implementation Patterns

Medallion works on any modern data platform. Here's how to implement it with common stacks.

PlatformBronzeSilver/GoldFormat
DatabricksUnity CatalogDelta Lake + dbtDelta
SnowflakeRAW databasedbt + SnowflakeNative tables
BigQueryraw_ datasetdbt + BQNative tables
AWS (Open)S3 + GlueSpark + dbtIceberg/Hudi

Folder/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_failed

Pro Tip

Use Separate Databases/Schemas

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.

7. Best Practices Checklist

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 → Silver (schema), Silver → Gold (business rules), Gold (metrics).

Apply access controls by layer

Bronze: data engineers only. Silver: data team. Gold: business users and dashboards.

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.

8. Frequently Asked Questions

What is Medallion Architecture?

Medallion Architecture is a data design pattern that organizes data into three layers: Bronze (raw data), Silver (cleaned and conformed), and Gold (business-level aggregates). It provides a logical organization for data in a lakehouse, enabling incremental improvement of data quality as it flows through each layer.

What is the difference between Bronze, Silver, and Gold layers?

Bronze contains raw, unprocessed data exactly as received from sources. Silver contains cleaned, deduplicated, and conformed data with standard schemas. Gold contains business-level aggregates and metrics optimized for specific use cases like dashboards and ML models.

When should I use Medallion Architecture?

Use Medallion Architecture when you have multiple data sources, need data quality improvement through stages, want to support both batch and streaming, or need to serve different consumers (analysts, data scientists, applications) with different data requirements.

Is Medallion Architecture only for Databricks?

No. While Databricks popularized the term, Medallion Architecture is a design pattern that works with any data platform: Snowflake, BigQuery, Redshift, or open-source stacks with Delta Lake, Apache Iceberg, or Apache Hudi. The principles of raw → cleaned → aggregated apply universally.

Visualize Your Medallion Architecture

Create clear diagrams showing your Bronze, Silver, and Gold layers. Document data flows, transformations, and ownership in minutes.