← Back to blog
// Spark Ops · Profiling

Spark Analyzer: Put a Number on Your Wasted Spark Compute, for Free

Spark Analyzer is a free CLI from Onehouse — pip install spark-analyzer — that reads your Spark History Server and reports, per application, how much of your allocated compute did useful work, how much was wasted, and what each stage was actually doing. We pointed it at four deliberately broken Spark jobs: the skewed one was wasting 40.8% of its compute.

July 16, 2026 / Written by Quanton Team
40.8%
compute wasted by our skewed demo job
81.8%
of the small-files job was load ops
3
commands to the first report

Overview

Data engineering runs on benchmark discourse. Every vendor — us included — publishes TPC-DS numbers, and they’re useful for comparing engines under controlled conditions. But TPC-DS is not your workload, and engineers know it. The question that actually decides anything is: “what would the performance be on my exact workloads?” Answering it for one or two jobs is an afternoon in the Spark UI. Answering it for hundreds of jobs, in aggregate, is the part nobody has tooling for.

There’s a second gap benchmarks leave open: TPC-DS mostly exercises the E — raw scan and transform performance. Real pipelines ETL differently. They spend their compute across extract, transform, and load in proportions that vary wildly by job — and that split determines everything: where your money goes, which fixes are worth making, and what an engine change would actually buy you. To reason about any of it, you need a tool that breaks down how much time each Spark job spends in each phase, classifies every stage, and shows exactly how your compute is being burned.

Spark Analyzer is that tool: a free CLI from Onehouse that reads your Spark History Server and answers, per application, how much of the compute you allocated did useful work, how much sat idle, which stages consumed it, and what kind of work — extract, transform, load — each stage was doing. In Onehouse’s analyses across organizations, 30–70% of Spark compute is typically wasted; the tool tells you where your jobs sit. Every section of our Spark performance tuning guide ends the same way — measure it — and this is the fastest free way to do that.

Rather than describe it in the abstract, we built four deliberately broken Spark jobs — one per failure pattern from the tuning guide — ran them on a local Spark 4.2 standalone cluster (4 executors × 2 cores), and pointed Spark Analyzer at the History Server. Everything below is real output.

How do I run Spark Analyzer?

Three commands — install, point at your History Server, analyze:

pip install spark-analyzer
spark-analyzer configure          # wizard: History Server URL, platform
spark-analyzer analyze --save-local

--save-local writes the analysis as JSON on your machine — nothing is uploaded anywhere. The report step turns a JSON into a three-sheet Excel workbook:

spark-analyzer report --input spark_analysis_output/spark_analysis_<app>.json

It works against open-source Spark, EMR, Databricks, Dataproc, and Fabric History Servers (--platform sets the baseline). One practical note from our run: you need real executors. Apps run with master("local[*]") report no executor metrics, so utilization comes back empty. Any actual cluster — YARN, Kubernetes, standalone, even a single-machine standalone like ours — works fine.

What we ran: four jobs, four failure patterns

Each job reproduces one pattern from the tuning guide, on the same 8-core standalone cluster:

ApplicationDeliberate problemWall-clockCompute usedResource efficiencyCompute waste
orders-enrichment-dailyData skew: one customer = 35% of 150M rows1.12 min5.03 core-min59.2%40.8%
sessionization-hourlySpill: global sort bigger than executor memory1.32 min7.89 core-min79.8%20.2%
feature-join-backfillShuffle-heavy 80M × 80M join0.48 min3.37 core-min90.0%10.0%
events-ingest-compaction-candidateSmall files: 2,400 tiny parquet files0.80 min5.34 core-min99.3%0.7%

Two things worth reading out of that table before we zoom in:

  • Skew shows up as waste. A straggler doesn’t keep the cluster busy — it keeps one core busy while the rest idle at a stage barrier. The analyzer prices that directly: 40.8% of everything we allocated to the skewed job did nothing.
  • High efficiency is not innocence. The spill and shuffle jobs score 80–90% “efficient” because their cores were genuinely busy — busy serializing spill files and moving bytes. Efficiency tells you whether you’re paying for idle metal; the stage-level sheet tells you whether the busy work was useful. You need both.

Reading the skew report

The application summary for orders-enrichment-daily says the quiet part in one row each:

Application Duration        1.12 minutes
Total Compute Minutes Used  5.03
Resource Efficiency         59.2%
Compute Waste               40.8% of allocated resources
Longest stage               Stage 0 (0.54 mins)
Most resource-intensive     Stage 4 (3.92 core-minutes)
Workflow breakdown          Transform 100.0%

The stage-level sheet classifies stages 0, 1, and 4 as TRANSFORM_TYPE_JOIN and pins 3.92 of the 5.03 core-minutes on stage 4 — the post-shuffle join+aggregate. So the analyzer’s verdict is: one join stage owns this job, and 40% of your spend idles around it. That’s the “which stage, and how much” answer that usually takes an afternoon of Spark UI archaeology.

From there, the Spark UI confirms why in one screen. Here’s the same application’s stage list — stage 4 reads 1,837.8 MiB of shuffle across 24 tasks:

Spark History Server stages page for the orders-enrichment-daily application, showing three completed stages with the final join stage reading 1,837.8 MiB of shuffle.

And stage 4’s detail page shows the classic skew fingerprint we described in the data skew deep dive: median task 4s, max 29s; median shuffle read 59.8 MiB, max 514.8 MiB. One task read 53 million of the stage’s 152 million records — our designed 35% hot key, found exactly:

Spark History Server stage detail page showing summary metrics with median task duration 4 seconds versus max 29 seconds, median shuffle read 59.8 MiB versus max 514.8 MiB, and the whale task visible in the task table with 1.4 GiB memory spill.

What the E/T/L classification catches

The small-files job is the interesting one. Its efficiency looks saintly — 99.3% — but the workflow sheet reveals what all that busy compute was doing:

Workflow typeStagesCompute minutesShare of job
Extract20.417.9%
Transform20.5310.3%
Load14.4081.8%

82% of the job is writing files. Nothing is “wasted” in the idle-cores sense — the job is simply spending five-sixths of its compute producing 2,400 tiny files that will make every downstream query slower. This is the exact profile one Spark Analyzer user found in production: with 60%+ of job time going to file writes, they reworked table layout and parallelism and got 40% faster jobs at 38% lower cost — no engine change. (If small files are your profile, clustering and compaction is the follow-up read.)

That classification is also what feeds the report’s Quanton projection: each stage type gets an expected acceleration range based on how Quanton’s engine handles that work (native scans for extract, vectorized operators for transform, native lakehouse writes for load). Our skewed join job projects 67–75% runtime reduction. And the projections are honest in the other direction too — for the toy small-files job, whose plain-parquet write Quanton has no special path for, the report says “similar performance” rather than inventing a win. In one real EMR migration, the analyzer predicted 27% acceleration; actual Quanton results significantly outperformed the estimate.

Where Spark Analyzer fits

QuestionTool
Is this job wasting the compute I allocate to it? Which stage? What kind of work?Spark Analyzer — offline, fleet-wide, free
Why is this specific stage slow right now, and what’s the fix?Quanton AI agent in the Spark UI — live diagnosis of skew, shuffle, OOM risk, and partition issues, with recommended config/code fixes
Task-level forensics on a single runSpark UI / History Server

Spark Analyzer is the survey instrument: run it across your History Server, rank applications by compute waste, and you have a data-driven backlog instead of a hunch. The per-GiB math for what those jobs would cost on Quanton is on the pricing page.

Takeaway

You can’t fix what you haven’t measured, and measuring used to mean event-log archaeology. Three commands now get you a per-application answer: our deliberately skewed job was wasting 40.8% of its allocated compute, our small-files job was spending 81.8% of its compute writing files, and the report named the stage responsible in both cases. It’s free, it runs locally, and your data stays put with --save-local.

pip install spark-analyzer

Run it against your History Server — then come back to the tuning guide with a ranked list of jobs worth fixing.

Frequently asked questions

What is Spark Analyzer?

Spark Analyzer (pip install spark-analyzer) is a free command-line tool from Onehouse that analyzes completed Spark applications through the Spark History Server API. It produces a per-application report with resource efficiency, compute waste, a stage-level breakdown, and each stage classified as extract, transform, or load — plus a projection of how much Quanton would accelerate the workload.

Does my data leave my environment when I run Spark Analyzer?

Not if you don't want it to. Run spark-analyzer analyze --save-local and all analysis is written as JSON files on your machine; the report is generated locally from those files. There are also --opt-out flags to hash sensitive fields like stage names and descriptions.

What platforms does Spark Analyzer work with?

Anything that exposes a Spark History Server API: open-source Spark, AWS EMR and EMR Serverless, Databricks (including Photon), GCP Dataproc, and Microsoft Fabric. You pass the platform with --platform so the analysis is interpreted against the right baseline.

What's in the Spark Analyzer report?

Three sheets. An application-level summary (wall-clock, total compute minutes, resource efficiency, compute waste, projected acceleration); a workflow-level summary splitting compute across extract, transform, and load; and a stage-level sheet with each stage's classification, shape, duration, compute minutes, and projected reduction range.

How is Spark Analyzer different from the Spark UI?

The Spark UI is a task-level microscope for one run; it doesn't aggregate or classify. Spark Analyzer reads the same event data and answers the aggregate questions: what fraction of allocated compute did useful work, which stages consumed it, and what kind of work each stage was. Use the analyzer to find the expensive stage, then the Spark UI to dissect it.

How accurate are the Quanton acceleration projections?

They're stated as ranges per stage type, not point estimates, and they're deliberately conservative. In one production migration from AWS EMR, Spark Analyzer predicted 27% acceleration and the actual Quanton result significantly outperformed the estimate. On jobs where Quanton wouldn't help, the report says 'similar performance' rather than inventing a win.

QT
Quanton Team
Data Infrastructure at Onehouse · Building Quanton
← Back to blog