Skip to content

docs: add benchmarking page to the contributors guide#2075

Merged
andygrove merged 7 commits into
apache:mainfrom
andygrove:docs/benchmarking-guide
Jul 17, 2026
Merged

docs: add benchmarking page to the contributors guide#2075
andygrove merged 7 commits into
apache:mainfrom
andygrove:docs/benchmarking-guide

Conversation

@andygrove

@andygrove andygrove commented Jul 17, 2026

Copy link
Copy Markdown
Member

Which issue does this PR close?

Closes #2074.

Rationale for this change

Benchmark numbers currently circulate through issues and PR descriptions with their conditions attached informally, which makes it hard to tell whether any two numbers are comparable. Results from the static planner and the adaptive (AQE) planner are especially easy to conflate, even though they come from different planners with materially different join behaviour.

benchmarks/README.md explains how to generate TPC-H data and run the benchmark locally, but not what cluster the published numbers came from, how to reproduce one, how Spark and Comet were configured for a cross-engine comparison, or which known issues to keep in mind when a query looks slow.

This adds one place that answers those questions and records the current result set.

What changes are included in this PR?

A new docs/source/contributors-guide/benchmarking.md, wired into the Contributors Guide nav in docs/source/index.rst:

  • What we measure, and why — work balance across executor tasks, and why AQE on and AQE off are always reported together.
  • Environment — the results currently come from a small homelab cluster with node-local data; the intent is to move to AWS with data in S3 once the numbers here are good. Stated explicitly so the numbers are read as relative comparisons on controlled hardware rather than absolute cloud throughput.
  • Reference cluster — the shape behind the numbers, and the reasoning for the parts that are easy to get wrong: one executor per node, node-local data rather than object storage, and headroom between the memory pool and the container limit.
  • Queries — all engines run the SQLBench-H query set from apache/datafusion-benchmarks, which is what makes the comparison apples-to-apples.
  • Running the benchmark — self-contained commands for Ballista, vanilla Spark, and Comet, so a result can be reproduced without repo-specific tooling.
  • Why compare against Comet — Comet and Ballista execute DataFusion physical plans using the same operators, so a gap points at distribution, scheduling, shuffle, and memory rather than operator speed. Includes the caveats that stop it being an operator-level A/B: Spark's optimizer and Spark's AQE produce the plan Comet accelerates, Comet falls back to the JVM for unsupported operators, and the two use different distribution models.
  • Results — a single current result set pinned to the exact commit, with Spark, Comet, Ballista AQE off, and Ballista AQE on side by side, plus conventions for recording a result.
  • Known issues found by benchmarking — brief orientation for reading a result, linking [EPIC] Adaptive Query Execution (AQE) #1359, Hash-join build side OOMs on TPC-H Q18 at SF1000 and does not shrink with target_partitions #2025, and Adaptive (AQE) execution hangs when a replan cancels an in-flight stage #2063.

The result table is now complete. TPC-H SF1000, 2 executors x (8 cores / 56 GiB), node-local data, 1 iteration, full-suite runs. Ballista at main @ 26b29391:

Engine Total Status
Comet 0.17.0 2738.5 s 22/22
vanilla Spark 3.5.3 4687.9 s 22/22
Ballista (AQE on) 6320.7 s 22/22
Ballista (AQE off) 6378.2 s 22/22

All 22 queries completed on all four configurations — no FAIL or OOM entries to record. Row counts agreed across every engine except Q15.

Measurement details recorded on the page rather than smoothed over:

  • The Ballista commit is pinned, not "main". 26b29391 removed the static planner's sort-merge-join broadcast conversion, which changes the AQE-off path specifically, so results either side of that commit are not comparable. The page says why the exact commit is recorded.
  • Every figure is a suite figure. Suite and standalone runs are not interchangeable: Q18 on Spark measured 458.0 s standalone versus 492.8 s within the suite, a 7.6% spread on the same build. The page makes "take the figure from a full suite run" an explicit convention.
  • Q15 row counts disagree: Spark 0, Comet and Ballista 1. Q15 is a multi-statement query and the reported count depends on which statement the harness treats as the result. Recorded as an open discrepancy, not resolved here.
  • Q11 returns 0 rows on every engine — its threshold constant is tuned for SF1.
  • Verified that the CometBench-H queries Spark/Comet run are textually identical to the SQLBench-H set Ballista runs (all 22 match once the licence header is ignored), so the comparison is on the same SQL.

Ready for review.

Are there any user-facing changes?

No code changes. Adds a documentation page to the Contributors Guide.

Document how Ballista is benchmarked at scale and record the current
result set in one place.

Covers the reference cluster shape and why it is shaped that way, the
shared SQLBench-H query set, and self-contained commands for running
TPC-H against Ballista, vanilla Spark, and Comet so a result can be
reproduced without repo-specific tooling.

Explains why Comet is the most informative comparison available -- it
executes DataFusion physical plans using the same operators -- along
with the caveats that keep it from being an operator-level A/B: Spark's
optimizer and AQE produce the plan Comet accelerates, Comet falls back
to the JVM for unsupported operators, and the two use different
distribution models.

Results are tracked as a single current set pinned to the exact commit
they came from, with AQE on and AQE off reported side by side. Most
entries are TBD pending measurement.
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jul 17, 2026
| Per executor | 8 cores, 56 GiB, `--memory-pool-size=48GB` |
| Per task slot | 8 concurrent tasks → 6 GB pool each |
| Scheduler | 1 |
| Data | TPC-H SF1000 Parquet, node-local disk |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May also be useful to specify how this data is generated (i.e. via the tpchgen-rs, partitioned, etc)

@andygrove andygrove changed the title docs: add benchmarking page to the contributors guide docs: add benchmarking page to the contributors guide [DO NOT MERGE] Jul 17, 2026
@andygrove andygrove changed the title docs: add benchmarking page to the contributors guide [DO NOT MERGE] docs: add benchmarking page to the contributors guide Jul 17, 2026
@andygrove
andygrove marked this pull request as ready for review July 17, 2026 08:00
@andygrove

Copy link
Copy Markdown
Member Author

This is the first clean run of the whole benchmark suite at this scale factor, so will merge this as a baseline and move onto debugging why performance is ~50% slower than Spark.

@andygrove
andygrove merged commit bce8190 into apache:main Jul 17, 2026
5 checks passed
@andygrove
andygrove deleted the docs/benchmarking-guide branch July 17, 2026 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a benchmarking page to the Contributors Guide

2 participants