cost optimization · 8 min read

Databricks Photon Cost and Performance Tradeoffs

By LakeSentry Team · Reviewed by Kristina Kazmina, Senior Software Engineer, LakeSentry

Photon roughly doubles DBUs per hour. Whether it lowers your bill depends on the workload. Pricing math, what to enable, and how to measure on yours.

Databricks Photon is priced at a premium: a Photon-enabled cluster consumes DBUs at a higher rate than the same instance on the standard Spark runtime — often around 2×, though it varies by SKU and cloud, so confirm yours on the Databricks pricing calculator. Whether that pays off depends on the workload, and the honest answer is sometimes, not always. This guide covers the pricing math, where Photon helps, where it doesn’t, and how to measure the difference on your own jobs.

For the broader cost-optimization playbook, see our Databricks cost optimization guide. That post enumerates Photon among other levers; this one zooms in on the DBU math and the decision framework.

How Photon Pricing Works

What Photon changes is consumption: the same instance burns DBUs faster with Photon on than on the standard runtime. Databricks documents this as a different DBU rate per instance type rather than a fixed multiplier, so treat ~2× as a starting estimate and confirm your own SKUs.

Using 2× as the premium, the trade is straightforward once you write it out:

  • 2× the DBUs per hour, 4× faster = total spend drops by about 50%.
  • 2× the DBUs per hour, 2× faster = total spend stays flat. You bought speed, not savings.
  • 2× the DBUs per hour, no speedup = spend doubles.

So the question isn’t “is Photon cheaper?” It’s “does this workload finish more than twice as fast with Photon on?”

Same compute, different bottlenecks Total DBUs consumed per job (lower is cheaper) Aggregation-heavy ETL Without Photon 10 DBUs With Photon 6 DBUs −40% Python UDF transform Without Photon 5 DBUs With Photon 9 DBUs +80%

Workloads Where Photon Helps

Photon is a native vectorized engine that processes columnar data in batches, so it pays off on CPU-bound work over Parquet or Delta scans:

  • Aggregations: GROUP BY, hash aggregates over fact tables
  • Hash joins over fact tables
  • Filters and projections over wide columnar tables
  • Delta writes
  • Window functions

The pattern is dense CPU work over columnar data — ETL writing large Delta tables, or SQL dashboards aggregating fact tables. When the speedup outpaces the higher per-hour DBU rate, total spend goes down.

Databricks reports up to 5× better price/performance on TPC-DS benchmarks. That’s a benchmark ceiling, not a floor any single job is guaranteed to hit. Your actual ratio depends on data size, the operations involved, and how much of the wall-clock is real compute versus data movement.

Workloads Where Photon Doesn’t Help (or Hurts)

Photon falls back to Spark when it hits an operation it doesn’t support. Jobs don’t break — but you pay the higher DBU rate on the parts that ran under Photon, even when most of the workload ran under Spark.

The unsupported set, per the docs:

  • UDFs (any language) — anything that crosses into a user-defined function
  • RDD and Dataset APIs — most legacy code, most MLlib training
  • Stateful streaming — stateless streaming is supported; stateful is not

That covers a lot of real production code: feature engineering built on Pandas UDFs, custom transforms wrapped as functions, ML model training, and most stateful Structured Streaming.

Two more cases worth flagging:

I/O-bound jobs. Photon accelerates the CPU side of execution. If a job’s wall-clock is dominated by reading from S3, ADLS, GCS, or an external source, there’s little left for the vectorized engine to speed up — the bottleneck is data movement, not compute.

Short queries. Per the docs, “queries that normally complete in under two seconds don’t see meaningful improvement,” because execution time is dominated by planning and scheduling overhead rather than data processing. Incremental jobs over small data chunks are the canonical case.

How to Measure Before and After

Three numbers tell you whether Photon paid off — and they live in three different system tables.

DBUs consumed are in system.billing.usage. Filter on product_features.is_photon to split Photon from non-Photon spend:

SELECT
  usage_metadata.job_id,
  product_features.is_photon AS photon_on,
  SUM(usage_quantity) AS dbus
FROM system.billing.usage
WHERE billing_origin_product = 'JOBS'
  AND usage_date >= current_date() - INTERVAL 30 DAYS
GROUP BY usage_metadata.job_id, product_features.is_photon
ORDER BY dbus DESC;

For the other two, join out:

  • Wall-clock comes from system.lakeflow.job_run_timelineperiod_end_time minus period_start_time, joined on job_id and the run ID (usage_metadata.job_run_id in billing, run_id in the timeline). A run longer than an hour spans several rows, so sum them per run.
  • Dollar cost is DBUs × the SKU’s price in system.billing.list_prices, joined on sku_name. Pull the price per SKU rather than assuming one rate — a Photon run can bill under a different SKU than the same job without it, so the per-DBU price isn’t guaranteed to match.

For an apples-to-apples read, run the same job twice — Photon on, then off — and compare all three. If re-running isn’t an option, watch each number on either side of the day you flipped the toggle.

A faster qualitative check is the Spark UI query plan DAG: Photon operators render in orange, Spark operators in blue. If the heavy stages of a slow job are blue, Photon isn’t accelerating the part that matters, and you’re paying the premium for nothing. (SQL warehouses run Photon always-on, so there’s no toggle to check there.)

A Decision Framework

The defaults that hold up across most environments:

Workload patternPhoton behaviorLikely cost direction
Large Parquet/Delta scans + aggregationsAcceleratedLower
Joins on fact tablesAcceleratedLower
Delta writesAcceleratedLower
SQL dashboards over wide tablesAcceleratedLower
ETL with Python/Pandas UDFsFalls back to SparkHigher
MLlib or RDD-based trainingFalls back to SparkHigher
I/O-bound copy or extract jobsLittle to accelerateHigher or flat
Short queries (<2s)No meaningful gainHigher
Streaming with stateful operatorsNot supported (falls back)Higher

“Lower” assumes the speedup outpaces the higher DBU rate — true for most accelerated workloads, but measure the ones close to the line. “Higher” means Photon either falls back or has nothing to accelerate, so the cluster pays the premium with no speedup — there, the fix is to turn Photon off.

Leave Photon on for SQL warehouses (always on, no toggle) and for classic all-purpose, jobs, and classic Lakeflow Spark Declarative Pipelines running ETL or SQL over Delta — Databricks enables it by default there.

Turn it off on clusters dedicated to UDF-heavy transforms, ML training, or streaming with stateful operators. The fallback doesn’t break anything, but you pay the premium for nothing.

Measure first on the mixed cases: a job that does a heavy aggregation followed by a UDF, or a pipeline that’s part Delta scan, part REST API extraction. Whichever half dominates the wall-clock decides the answer.

Photon is a performance tool that sometimes lowers cost as a side effect of finishing faster. Whether it does on any given workload depends on the operators in your code, the size of the data, and how much of the wall-clock is CPU work. The only way to know is to measure DBUs and dollar cost, not just runtime.

For how DBU pricing fits into the broader cost picture, see DBUs explained and Databricks pricing explained.

FAQ

1. Is Databricks Photon always more expensive than running without it?

Per hour, yes — a Photon-enabled cluster consumes DBUs at a higher rate than the same instance on the standard Spark runtime. Per job, no. If Photon cuts wall-clock by more than the DBU premium, total DBUs go down even at the higher hourly rate.

2. Can I use Photon for some jobs but not others?

Photon is a cluster-level setting, not a per-job one. A job running on its own job cluster sets Photon independently — just configure that cluster. The only awkward case is several jobs sharing one all-purpose cluster: point the job you want to differ at a separate cluster with Photon toggled the other way. SQL warehouses and serverless pipelines run Photon always-on, with no toggle.

3. How do I check if Photon is accelerating a query?

Open the query plan DAG in Spark UI: Photon operators show in orange, Spark operators in blue. If the heavy stages of a slow job are blue, Photon isn’t accelerating the part that matters, and you’re paying the higher rate without the corresponding speedup. On SQL warehouses Photon is always on, so there’s nothing to toggle.

4. Does Photon help with ML training?

Generally no. Most MLlib and custom training code uses RDD or Dataset APIs that Photon doesn’t support, so execution falls back to Spark — you pay the higher hourly rate without the acceleration. Inference and feature engineering on Delta tables are different, and often do qualify.

5. Where can I see Photon-on vs Photon-off DBU usage?

In system.billing.usage, split usage_quantity by product_features.is_photon to see how much of your spend ran with Photon versus without. It’s most useful on jobs and pipelines you can actually toggle — SQL warehouses run Photon always-on, so there’s nothing to compare there.

See Photon's real impact on your workloads

Free tier — unlimited workspaces, no credit card. Connect in minutes.

Evaluating Databricks cost tools? Compare them side by side →