Compute costs make up 80-90% of your data engineering bill. Here are the architecture decisions that cut them dramatically.
Your pipeline runs every night. Four hours of compute. Three terabytes of data. And here's the uncomfortable part, you're probably reprocessing 95% of data that hasn't changed.
That's not a pipeline problem. That's an architecture problem. And it's costing your team thousands every month.
In most modern data platforms, compute makes up 80–90% of total data engineering spend. The good news? The fixes aren't exotic. They're fundamental engineering decisions, the kind you can learn, practice, and apply immediately.
This article walks through five practical techniques that can reduce your Databricks pipeline costs by up to 80%. Each one maps to a core concept we teach in BricksNotes.
Before optimizing, you need to understand where money goes.
graph LR
A[Data Sources] --> B[Ingestion Compute]
B --> C[Transformation Compute]
C --> D[Storage I/O]
D --> E[Query Compute]
style B fill:#e74c3c,color:#fff
style C fill:#e74c3c,color:#fff
style E fill:#f39c12,color:#fffThe red boxes are where most of your bill lives. Ingestion and transformation compute dominate because they run on clusters, and clusters bill by the minute.
Every optimization technique in this article targets those red boxes.
This is the single highest-impact change you can make.
Most pipelines start as full reloads, read everything, transform everything, write everything. It works when your data is small. But at 3TB, you're burning compute on 2.95TB of unchanged data every single run.
The best optimization isn't faster code. It's processing less data.
Instead of reprocessing everything, identify what's new or changed and process only that.
-- Instead of overwriting the entire table:
-- INSERT OVERWRITE TABLE silver.customers SELECT * FROM bronze.customers
-- Process only changes:
MERGE INTO silver.customers AS target
USING (
SELECT * FROM bronze.customers
WHERE _ingested_at > current_timestamp() - INTERVAL 1 HOUR
) AS source
ON target.customer_id = source.customer_id
WHEN MATCHED AND source.updated_at > target.updated_at THEN
UPDATE SET *
WHEN NOT MATCHED THEN
INSERT *This pattern is covered in depth in our Incremental Processing chapter, where you learn to build pipelines that process only what's changed. For automated ingestion, Databricks Lakeflow now provides unified ingestion and orchestration under Unity Catalog.
For more advanced patterns, like tracking historical changes with Type 2 Slowly Changing Dimensions, our SCD Patterns chapter walks through the complete implementation.
Cost impact: A pipeline processing 3TB daily was reduced to processing ~150GB of changes. That's a 95% reduction in data scanned.
from delta.tables import DeltaTable
from pyspark.sql import functions as F
# Read only new records from source
new_records = (
spark.read.table("bronze.customers")
.filter(F.col("_ingested_at") > F.current_timestamp() - F.expr("INTERVAL 1 HOUR"))
)
# Merge into target
target = DeltaTable.forName(spark, "silver.customers")
target.alias("t").merge(
new_records.alias("s"),
"t.customer_id = s.customer_id"
).whenMatchedUpdateAll(
condition="s.updated_at > t.updated_at"
).whenNotMatchedInsertAll().execute()If you're new to working with DataFrames and these transformation patterns, our DataFrames Fundamentals chapter builds the foundation you need.
This is the silent performance killer most teams don't diagnose.
Every write to a Delta table creates new Parquet files. If you're ingesting data every 10 minutes, that's 144 new files per day per partition. After a month, Spark is managing thousands of tiny files, and spending more time on metadata than actual computation.
We wrote an entire deep-dive on this: The Small File Problem Is Quietly Killing Your Delta Lake Performance. But here's the cost-focused summary.
-- Compact small files into optimal ~1GB files
OPTIMIZE silver.customers;
-- Co-locate related data for faster range queries
OPTIMIZE silver.orders ZORDER BY (customer_id, order_date);
-- Clean up old file versions
VACUUM silver.customers RETAIN 168 HOURS;For tables on Delta Lake, Liquid Clustering handles this automatically and replaces the need for manual ZORDER:
CREATE TABLE silver.orders (
order_id BIGINT,
customer_id BIGINT,
order_date DATE,
amount DECIMAL(10,2)
) CLUSTER BY (customer_id, order_date);Our Storage & File Optimization chapter explains why file sizes matter and how different formats affect performance. And our Delta Lake Architecture chapter covers the transaction log mechanics that make OPTIMIZE and VACUUM possible.
Cost impact: Reducing 4,000 small files to 40 optimized files cut query times by 60%, which means smaller clusters and shorter runtimes.
This isn't a code optimization. It's an infrastructure decision that can cut your bill in half overnight.
| Cluster Type | Use Case | Cost Impact |
|---|---|---|
| All-Purpose (Interactive) | Development, exploration | Highest, runs continuously |
| Job Clusters | Scheduled pipelines | Lower, starts and stops with the job |
| SQL Warehouses | BI queries, dashboards | Optimized for SQL workloads |
The most common mistake: running production pipelines on interactive clusters that stay alive 24/7.
A job cluster that runs for 40 minutes costs a fraction of an interactive cluster that runs all day.
Our Production Orchestration chapter covers how to design job configurations, set cluster policies, and schedule pipelines that use compute efficiently.
For understanding how to monitor whether your clusters are right-sized, our Observability & Debugging chapter teaches you to read the Spark UI and identify wasted resources.
Cost impact: Switching from interactive to job clusters typically saves 40-60% on compute alone.
The Medallion Architecture isn't just about data quality. It's a cost optimization strategy.
graph TD
A[Raw Sources] --> B[Bronze Layer]
B --> C[Silver Layer]
C --> D[Gold Layer]
D --> E[Dashboards and Reports]
D --> F[ML Models]
B -.-> G[Full data, minimal compute]
C -.-> H[Clean once, read many times]
D -.-> I[Pre-aggregated, fast queries]Here's why this saves money:
Bronze layer: Ingest raw data with minimal transformation. Low compute cost. You're just landing data.
Silver layer: Clean, deduplicate, and validate once. Every downstream consumer reads clean data without re-cleaning it. Our Data Quality Engineering chapter covers the validation patterns that belong here.
Gold layer: Pre-aggregate and denormalize for specific use cases. Instead of 50 analysts running complex joins on Silver tables, they query pre-built Gold tables that return in seconds.
Our Lakehouse Architecture Design chapter walks through the complete Bronze-Silver-Gold pattern with practical examples.
Without a Gold layer, every dashboard query pays the cost of a full transformation. With a Gold layer, you pay that cost once.
Cost impact: Pre-aggregated Gold tables reduced BI query compute by 70% in one production environment.
Layered architecture only works if your schemas are clean and evolve gracefully. Our Schema Management & Evolution chapter teaches you to handle column additions, type changes, and schema drift without breaking downstream consumers.
Photon is Databricks' optimized execution engine. It's a C++ native vectorized engine that replaces parts of the Spark JVM runtime.
What this means in practice:
-- Check if Photon is active on your cluster
SELECT *
FROM system.runtime.cluster_events
WHERE event_type = 'PHOTON_ENABLED';Photon is most effective on:
Our Performance Optimization chapter covers partitioning strategies and performance tuning that complement Photon, because even the fastest engine can't fix a poorly partitioned table.
For understanding how SQL queries execute and where bottlenecks occur, our SQL Query Fundamentals chapter builds the mental model you need.
Cost impact: Photon-enabled clusters completed the same workload 3x faster, allowing cluster downsizing.
Here's what happens when you combine all five techniques:
| Optimization | Individual Savings | Cumulative Effect |
|---|---|---|
| Incremental processing | 50-80% less data processed | Foundation |
| Small file compaction | 30-60% faster queries | Multiplied by less data |
| Job clusters | 40-60% less cluster time | Applied to shorter jobs |
| Medallion architecture | 50-70% less redundant compute | Fewer transformations |
| Photon execution | 2-4x faster runtime | Faster on optimized data |
A real-world pipeline processing ~3TB daily was optimized from 4 hours runtime to 40 minutes. Monthly compute cost dropped by over 80%.
That's not one trick. That's five fundamentals working together.
Optimization isn't a one-time event. Pipelines evolve. Data volumes grow. New sources get added.
Build a monitoring habit:
-- Check table sizes and file counts regularly
DESCRIBE DETAIL silver.customers;
-- Review job durations over time
SELECT
job_name,
AVG(duration_seconds) AS avg_duration,
MAX(duration_seconds) AS max_duration,
COUNT(*) AS run_count
FROM job_run_history
WHERE start_time > current_date() - INTERVAL 30 DAYS
GROUP BY job_name
ORDER BY avg_duration DESC;Our Observability & Debugging chapter teaches you to set up monitoring that catches performance regressions before they become cost problems.
Every technique in this article maps to a fundamental concept. Here's your learning path:
| Cost Problem | Root Cause | BricksNotes Chapter |
|---|---|---|
| Reprocessing unchanged data | No incremental strategy | Incremental Processing |
| Slow queries despite small data | Small file accumulation | Storage & File Optimization |
| Clusters running all day | Wrong cluster type | Production Orchestration |
| Redundant transformations | No layered architecture | Lakehouse Architecture Design |
| Slow aggregations | No performance tuning | Performance Optimization |
| Data quality issues causing reruns | No validation layer | Data Quality Engineering |
| Schema changes breaking pipelines | No evolution strategy | Schema Management & Evolution |
| Can't diagnose bottlenecks | No observability | Observability & Debugging |
We've covered several related topics in depth:
Cost optimization isn't about clever hacks. It's about understanding how data systems work, how files are organized, how compute is allocated, how transformations flow through layers.
The engineers who build cost-efficient pipelines are the ones who understand these fundamentals deeply. They don't guess. They diagnose, measure, and apply the right pattern for the right problem.
That's what BricksNotes teaches. Not tools. Not syntax. The thinking behind the engineering.
Start with the chapter that matches your biggest cost problem. The savings will follow.