Reference Architecture Patterns
Analyze production-grade reference architectures including the Modern Data Lakehouse, Enterprise SQL Data Warehouse, Lambda and Kappa patterns, and multi-platform Data Mesh topologies.
Reference Architecture Patterns
Bottom Line: No single architecture pattern fits all scenarios. This section provides production-grade reference architectures for the most common enterprise data platform use cases, annotated with specific service choices and the reasoning behind them.
12.1 Pattern 1: Modern Data Lakehouse (Databricks-Centric)
Best For: Data engineering + ML-heavy organisations, open format preference, Python-native teams.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MODERN DATA LAKEHOUSE ARCHITECTURE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
DATA SOURCES INGEST STORE (Bronze)
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Operational โ Debezium โ MSK / Kafka โ Streams โ S3 Raw Zone โ
โ Databases โโโโโโโโโโโบโ (Event Stream) โโโโโโโโโโบโ (JSON/Avro) โ
โ (RDS, Mongo) โ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโ
โ โ โ
โ SaaS Apps โ Fivetran โ AWS AppFlow โ โโโโโโโโโโผโโโโโโโโโ
โ (Salesforce โโโโโโโโโโโบโ (Batch/Sched.) โโโโโโโโโโบโ Auto Loader โ
โ HubSpot) โ โโโโโโโโโโโโโโโโโโโโ โ โ Bronze Delta โ
โ โ โโโโโโโโโโฌโโโโโโโโโ
โ Clickstream โ Kinesis โ Kinesis Streams โ โ
โ (Web/App) โโโโโโโโโโโบโ โ Firehose โS3 โ โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
PROCESS (Databricks)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DATABRICKS PLATFORM โ
โ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ DLT Pipeline โ โ Batch Jobs โ โ ML Workflows โ โ
โ โ (BronzeโSilver โ โ (dbt on โ โ (MLflow + Feature โ โ
โ โ โGold via DLT) โ โ Databricks) โ โ Store + AutoML) โ โ
โ โโโโโโโโโโโฌโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโโโ โโโโโโโโโโโฌโโโโโโโโโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโ โ
โ โ UNITY CATALOG โ โ
โ โ Metastore: Bronze โ Silver โ Gold โ Feature Store โ ML Models โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
SERVE
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SQL Warehouse โโโบ BI Tools (Power BI, Tableau, Looker) โ
โ Databricks AI Gateway โโโบ LLM-powered apps โ
โ Model Serving REST API โโโบ Real-time ML predictions โ
โ Delta Sharing โโโบ External partners / downstream consumers โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Implementation Checklist
# 1. Set up Unity Catalog metastore (one-time, per region)
# - Create storage credential for S3
# - Create external location pointing to your S3 bucket
# - Create catalogs: bronze, silver, gold, ml_prod
# 2. Configure Auto Loader for each source
auto_loader_config = {
"format": "cloudFiles",
"cloudFiles.format": "json", # or avro, parquet, csv
"cloudFiles.schemaLocation": "s3://my-lake/schemas/{table}/",
"cloudFiles.inferColumnTypes": "true",
"cloudFiles.maxFilesPerTrigger": 500
}
# 3. Deploy DLT pipeline for Medallion processing
# (See 05_Data_Ingestion.md for full DLT code)
# 4. Set up Databricks Workflows for orchestration
workflow_config = {
"tasks": [
{"task_key": "ingest", "notebook_task": {"notebook_path": "/pipelines/01_ingest"}},
{"task_key": "transform", "depends_on": [{"task_key": "ingest"}],
"notebook_task": {"notebook_path": "/pipelines/02_transform"}},
{"task_key": "ml_features", "depends_on": [{"task_key": "transform"}],
"notebook_task": {"notebook_path": "/pipelines/03_features"}}
]
}
# 5. Configure model serving endpoint
# (See 07_AI_and_ML.md for model serving code)12.2 Pattern 2: Enterprise SQL Data Warehouse (Snowflake-Centric)
Best For: SQL-dominant analytics, large analyst teams, cross-org data sharing, minimal engineering overhead.
dbt Project Structure for Snowflake
dbt_project/
โโโ models/
โ โโโ staging/ โ Stage raw Fivetran/Snowpipe tables
โ โ โโโ stg_orders.sql
โ โ โโโ stg_customers.sql
โ โ โโโ stg_products.sql
โ โโโ intermediate/ โ Complex joins and business logic
โ โ โโโ int_customer_order_history.sql
โ โ โโโ int_product_performance.sql
โ โโโ marts/ โ Final, business-facing models
โ โโโ finance/
โ โ โโโ fct_revenue.sql
โ โโโ marketing/
โ โ โโโ dim_customer_segments.sql
โ โโโ core/
โ โโโ fct_orders.sql
โโโ macros/ โ Reusable Jinja macros
โโโ tests/ โ Data quality tests
โ โโโ generic/
โ โโโ singular/
โโโ dbt_project.yml
-- Example dbt model: marts/finance/fct_revenue.sql
{{
config(
materialized='incremental',
unique_key='order_id',
incremental_strategy='merge',
cluster_by=['order_date'],
post_hook=[
"{{ grant_select_to_role('fct_revenue', 'ANALYST_FINANCE') }}"
]
)
}}
WITH orders AS (
SELECT * FROM {{ ref('int_customer_order_history') }}
{% if is_incremental() %}
WHERE order_date >= (SELECT MAX(order_date) - INTERVAL '3 days' FROM {{ this }})
{% endif %}
),
exchange_rates AS (
SELECT * FROM {{ ref('stg_exchange_rates') }}
),
final AS (
SELECT
o.order_id,
o.customer_id,
o.region,
o.order_date,
o.revenue AS revenue_local,
o.currency,
o.revenue * er.rate_to_usd AS revenue_usd,
o.product_category,
CURRENT_TIMESTAMP() AS dbt_updated_at
FROM orders o
LEFT JOIN exchange_rates er
ON o.currency = er.currency_code
AND o.order_date = er.rate_date
)
SELECT * FROM final12.3 Pattern 3: Lambda Architecture (Real-Time + Batch)
Best For: Use cases requiring both real-time dashboards AND accurate historical analytics (e.g., fraud detection, operational dashboards).
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LAMBDA ARCHITECTURE โ
โ โ
โ Data Source (e.g., payment events) โ
โ โ โ
โ โโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Amazon MSK / Kinesis โ โ
โ โ (Event backbone) โ โ
โ โโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ SPEED LAYERโ BATCH LAYERโ โ
โ โโโโโโโโโโโโผโโโโโโโโโโโ โโโโโโโโโโโโโผโโโโโโโโโโโโโโโ โ
โ โ Databricks โ โ Databricks โ โ
โ โ Structured Streaming โ โ Batch Jobs โ โ
โ โ โ 30-second windows โ โ โ Full reprocessing โ โ
โ โ โ Redis / DynamoDB โ โ โ Gold Delta tables โ โ
โ โ (low latency) โ โ (accurate) โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโโ โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโ โ
โ โ SERVING LAYER โ โ
โ โ Query router: real-time data + historical data โ โ
โ โ โ Dashboards see merged view โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Lambda: Speed layer (Structured Streaming โ live metrics)
speed_query = (
kafka_stream
.withWatermark("event_timestamp", "1 minute")
.groupBy(
F.window("event_timestamp", "30 seconds"),
"region"
)
.agg(
F.sum("amount").alias("live_revenue"),
F.count("*").alias("live_tx_count")
)
.writeStream
.format("delta")
.outputMode("append")
.option("checkpointLocation", "s3://my-bucket/ckpt/speed/")
.trigger(processingTime="5 seconds")
.toTable("analytics.realtime.revenue_windows_5s")
)
# Lambda: Batch layer (accurate, reprocessable historical data)
from pyspark.sql import SparkSession
def run_batch_reprocess(date: str):
"""Run daily batch to correct any speed layer approximations."""
daily_data = spark.table("ecommerce_prod.bronze.payment_events") \
.filter(F.col("event_date") == date)
accurate_aggregates = daily_data.groupBy("region", "event_date") \
.agg(
F.sum("amount").alias("total_revenue"),
F.countDistinct("customer_id").alias("unique_customers"),
F.count("*").alias("transaction_count")
)
accurate_aggregates.write \
.format("delta") \
.mode("overwrite") \
.option("replaceWhere", f"event_date = '{date}'") \
.saveAsTable("analytics.gold.daily_revenue_accurate")12.4 Pattern 4: Kappa Architecture (Stream-Only)
Best For: When batch and stream processing can be unified (modern preferred approach). Databricks Structured Streaming handles both.
12.5 Pattern 5: Hybrid Multi-Platform (Best-of-Breed)
Best For: Large enterprises, 100+ engineers, complex workload mix, ML + BI + sharing all critical.
Data Flow: Databricks โ Snowflake (Production Pattern)
# Option 1: Write Gold Delta tables to S3, Snowpipe loads into Snowflake
# (Recommended for decoupling)
# Step 1: Databricks writes Gold table to S3 as Parquet
(
gold_df.write
.format("parquet")
.mode("overwrite")
.partitionBy("order_date")
.save("s3://my-lake/snowflake-landing/gold/orders/")
)
# Step 2: Snowpipe (configured with SQS auto-ingest) picks up new files automatically
# (See 05_Data_Ingestion.md for Snowpipe setup)
# Option 2: Use Spark Snowflake Connector (direct write, simpler)
(
gold_df.write
.format("snowflake")
.option("sfURL", "myorg-myaccount.snowflakecomputing.com")
.option("sfDatabase", "ECOMMERCE")
.option("sfSchema", "GOLD")
.option("sfWarehouse", "LOADER_WH")
.option("dbtable", "ORDERS_DAILY")
.option("private_key_file", "/path/to/rsa_key.p8")
.mode("overwrite")
.save()
)
# โ ๏ธ Direct connector is simpler but creates tight coupling
# โ ๏ธ Snowflake bills for compute on the receiving COPY operation12.6 Pattern 6: Data Mesh with Shared Infrastructure
Best For: Large organisations (>500 engineers), multiple independent domains, federated governance.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DATA MESH TOPOLOGY โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ DOMAIN: Finance โ โ DOMAIN: Marketingโ โ DOMAIN: Ops โ โ
โ โ โ โ โ โ โ โ
โ โ Own: Tables, โ โ Own: Tables, โ โ Own: Tables, โ โ
โ โ Pipelines, SLAs โ โ Pipelines, SLAs โ โ Pipelines, SLAs โ โ
โ โ โ โ โ โ โ โ
โ โ Catalog: UC โ โ Catalog: UC โ โ Catalog: UC โ โ
โ โ (finance.*) โ โ (marketing.*) โ โ (ops.*) โ โ
โ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ SHARED INFRASTRUCTURE PLANE โ โ
โ โ โ โ
โ โ Unity Catalog Metastore (central governance, federated access) โ โ
โ โ S3 Data Lake (shared storage, domain-prefix namespacing) โ
โ โ Databricks Platform (shared compute, domain-isolated workspace) โ
โ โ MSK / Kinesis (shared event bus) โ โ
โ โ Snowflake (shared serving layer, cross-domain BI)โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Unity Catalog Multi-Domain Setup
-- Central platform team sets up metastore and top-level catalogs
-- Domain teams own their catalogs
-- Finance domain catalog
CREATE CATALOG finance_prod;
ALTER CATALOG finance_prod SET OWNER TO `finance-data-team@company.com`;
GRANT USE CATALOG ON CATALOG finance_prod TO `finance-data-team@company.com`;
GRANT CREATE SCHEMA ON CATALOG finance_prod TO `finance-data-team@company.com`;
-- Marketing domain catalog
CREATE CATALOG marketing_prod;
ALTER CATALOG marketing_prod SET OWNER TO `marketing-data-team@company.com`;
-- Cross-domain access (controlled, explicit grants)
-- Marketing team needs Finance's revenue data (approved cross-domain use)
GRANT SELECT ON TABLE finance_prod.gold.revenue_by_customer
TO `marketing-data-team@company.com`;
-- Shared "platform" catalog for cross-domain reference data
CREATE CATALOG shared_platform;
GRANT SELECT ON ALL TABLES IN CATALOG shared_platform
TO `all-data-teams@company.com`;12.7 Architecture Anti-Patterns to Avoid
โ ANTI-PATTERN 1: Using Snowflake as your primary ETL engine
Snowflake VWs billed per credit-hour = expensive for heavy Spark-equivalent transforms
โ Use Databricks or Glue for transformation, Snowflake for serving
โ ANTI-PATTERN 2: Running all workloads on one large Redshift cluster
A single large provisioned cluster cannot optimally serve BI + ETL + ML simultaneously
โ Isolate workloads with Redshift Serverless or separate clusters
โ ANTI-PATTERN 3: All-Purpose Databricks clusters for production pipelines
All-Purpose clusters cost 2x more than Job clusters
โ Always use Job clusters for scheduled pipelines
โ ANTI-PATTERN 4: S3 with CSV files and no partitioning
Athena at $5/TB scanned on 10TB CSV = $50/query
โ Convert to Parquet, partition by date, add file compression
โ ANTI-PATTERN 5: Snowflake Time Travel on every table for 90 days
90-day Time Travel on a table with heavy updates = 3-5x storage multiplication
โ Tune Time Travel per table: 1 day for staging tables, 90 days for critical facts
โ ANTI-PATTERN 6: Building ML models directly in Snowflake SQL
Snowflake Cortex ML Functions are good for simple regression/classification
But complex feature engineering on 100M+ rows needs Spark (Databricks)
โ ANTI-PATTERN 7: Ignoring the Glue Catalog
Building AWS data lakes without registering tables in Glue Catalog means
Athena, EMR, Redshift Spectrum cannot discover or join your data
โ Always register all datasets in Glue Catalog from day 1
โ ANTI-PATTERN 8: Point-to-point platform integrations without event bus
Direct RDS โ Redshift, direct CRM โ Snowflake without a central event bus
creates a brittle, unobservable architecture
โ Route all events through MSK or Kinesis as the single source of truth
12.8 Quick Reference: Service Equivalence Map
| Capability | AWS | Snowflake | Databricks |
|---|---|---|---|
| Object Storage | S3 | S3/GCS/ADLS (managed) | S3/GCS/ADLS (customer) |
| SQL Warehouse | Redshift | Virtual Warehouse | SQL Warehouse |
| Ad-hoc SQL | Athena | Snowsight + VW | SQL Warehouse |
| ETL/ELT Jobs | Glue ETL | Snowpark, dbt | Databricks Jobs, dbt |
| Stream Processing | Kinesis Analytics, MSK | โ (Tasks = micro-batch) | Structured Streaming |
| Metadata Catalog | Glue Data Catalog | Snowflake native | Unity Catalog |
| Governance | Lake Formation | Native policies | Unity Catalog |
| Orchestration | MWAA (Airflow), Step Functions | Tasks + DAGs | Databricks Workflows |
| Notebooks | SageMaker Studio | Snowflake Notebooks | Databricks Notebooks |
| ML Training | SageMaker Training | Snowpark ML | MLflow + Spark |
| LLM Integration | Bedrock | Cortex | Mosaic AI / AI Gateway |
| Data Sharing | Data Exchange, Redshift Sharing | Data Sharing, Marketplace | Delta Sharing |
| CI/CD Integration | CodePipeline, GitHub Actions | SchemaChange, dbt Cloud | Databricks Asset Bundles |
| Monitoring | CloudWatch | ACCOUNT_USAGE | Databricks Observability |