VecRuntime on TPC-DS 10 TB, AWS Graviton4 (11 x m8gd.4xlarge)

VecRuntime runs Spark SQL's filters, projections, aggregates, sorts and joins on Arrow-layout batches with the Java Vector API -- on the JVM, no native code -- and moves batches between executors over its own Arrow Flight shuffle. This page is its TPC-DS 10 TB run on eleven Graviton4 nodes, set against the totals quanton.dev/benchmarks (Onehouse), read 2026-10-21 publishes for other engines on the same instance type and count.

VecRuntime, 99 queries
2,430 s
10 TB · 11 x m8gd.4xlarge
vs OSS Apache Spark (published)
5.0x
12,200 s against 2,430 s
Second pass / first pass
2,430 / 2,449 s
0.8% apart

Total runtime

Lower is better. The grey bars are published totals, not re-run here (see the notes); VecRuntime's is this page's run.

EngineTotal (s)Its time / VecRuntime'sSource
OSS Apache Spark12,2005.02xpublished
DataFusion Comet (tuned)9,1223.75xpublished
Gluten + Velox (tuned)8,5633.52xpublished
Databricks Photon 18.22,5501.05xpublished
VecRuntime2,430this page
Quanton v0.43.02,0340.84xpublished

Totals as published on quanton.dev: the Quanton v0.43.0 suite total, and the other engines from the Quanton storage-aware Spark benchmark deck. Comet and Gluten are tuned configurations (their out-of-the-box runs failed with out-of-memory errors on Q67 and Q93). Not re-run here; per-query times are not published.

Where the time goes

The ten longest queries:

QuerySecondsShare of total
q23207.38.5%
q24196.08.1%
q14156.56.4%
q78154.96.4%
q67151.26.2%
q28109.14.5%
q9393.83.9%
q6477.83.2%
q473.53.0%
q5062.92.6%

Across the 99 queries:

MeasureValue
Executor time101.9 h
GC time0.81 h
Spill942 GiB
Shuffle written2.23 TiB

Per query

Seconds per query, both passes (hover for values).

Benchmark infrastructure

Methodology. Two full passes of the 99 queries, one after the other, each with the cluster to itself and all 11 executors up (checked before the first query). Each query ran once after its plan was compiled; its time is the wall-clock of its execution as the runner measures it, and the total is the sum over the queries. The page shows pass 2 and, per query, pass 1 next to it.

Test environment

ComponentConfiguration
DatasetTPC-DS scale factor 10000 (10 TB), Parquet on Amazon S3; the 99 queries (q14, q23, q24 and q39 as the sums of their a and b parts)
ClusterAmazon EKS; 11 x m8gd.4xlarge executor nodes (16 vCPU AWS Graviton4, 64 GB, local NVMe for shuffle and spill), one executor per node; the driver on a separate c8g.xlarge node
Executors11 executors x 15 cores; 20 GB heap + 10 GB overhead + 28,928 MB off-heap (spark.memory.offHeap.size), 6 GB direct memory; G1; driver 3 cores x 4 GB
StorageAmazon S3 through Hadoop S3A; VecRuntime's native Parquet scan (VectorParquetScanExec)

Versions

ComponentVersion
VecRuntimePR #911's head 60c645c2, merged as main e74d0be5 (2026-10-21): DistinctBelowSemiJoin for semi and anti joins (#906, #907), operator arenas on the native pool (#909), pool accounting (#911); arm64 image
Spark (VecRuntime)4.1.3, Scala 2.13, Amazon Corretto 25.0.4.1

VecRuntime configuration

spark.plugins=io.vecruntime.spark.VectorPlugin
spark.shuffle.manager=org.apache.spark.sql.vecruntime.shuffle.VectorShuffleManager
spark.sql.shuffle.partitions=1500, spark.sql.adaptive.enabled=true (coalescing on)
spark.memory.offHeap.enabled=true, spark.memory.offHeap.size=28928m
spark.vecruntime.exec.strictFloatingPoint=false, spark.vecruntime.exec.sortMergeJoin.enabled=true
spark.vecruntime.memory.poolAccounting.enabled=true (the default)
Executors: G1, -XX:MaxDirectMemorySize=6g, Arrow on its Unsafe allocation manager; glibc malloc defaults (no MALLOC_ARENA_MAX, no MALLOC_MMAP_THRESHOLD_)
--add-modules=jdk.incubator.vector --enable-native-access=ALL-UNNAMED (driver and executors)

Notes

  • The other engines' totals are the ones quanton.dev publishes for TPC-DS 10 TB on 11 x m8gd.4xlarge; they were not re-run here, and only their totals are published, so the comparison is of totals only.
  • Their setups are not documented to the level of this page (dataset generation and table format, Spark versions, executor layout, whether the driver is one of the 11 nodes). Treat the cross-engine bars as indicative, not as a controlled comparison.
  • VecRuntime needs Spark 4.1+ and JDK 25.
  • A third pass at 600 shuffle partitions took 2,520 s (1,500 partitions stays the setting); the same configuration before #909 and #911, with MALLOC_ARENA_MAX=2 and MALLOC_MMAP_THRESHOLD_=131072, took 2,618 s. See issue #869.
  • q18 and q68 end in LIMIT 100 over rows with tied sort keys, so their checksums can differ between runs and engines; every other query's result is the same in both passes.

All queries

Seconds per query
QueryPass 2 (s)Pass 1 (s)Difference
q18.18.1-0.0
q212.912.8-0.1
q35.96.0+0.1
q473.573.0-0.5
q517.918.0+0.1
q63.02.9-0.0
q711.911.6-0.3
q84.23.5-0.7
q953.252.3-0.9
q104.24.3+0.1
q1130.330.3+0.0
q122.82.7-0.0
q1314.713.6-1.1
q14156.5153.5-3.1
q153.74.0+0.3
q1651.149.8-1.4
q1710.39.5-0.8
q1812.913.1+0.1
q194.03.8-0.1
q202.52.4-0.1
q211.61.6-0.0
q224.34.4+0.1
q23207.3201.0-6.4
q24196.0196.0+0.0
q258.18.1+0.0
q267.16.5-0.6
q2710.79.9-0.8
q28109.1112.7+3.6
q2922.122.5+0.3
q306.77.3+0.7
q316.86.7-0.1
q321.61.9+0.3
q333.63.2-0.4
q345.45.3-0.1
q359.69.5-0.1
q368.27.7-0.5
q3716.516.1-0.4
q3834.034.3+0.3
q398.18.3+0.1
q405.65.7+0.1
q410.60.6+0.0
q421.61.9+0.3
q436.56.6+0.1
q4459.059.2+0.2
q453.23.2+0.0
q467.47.2-0.2
q4723.823.7-0.0
q4810.611.0+0.4
q4915.415.8+0.4
q5062.964.2+1.3
q5112.712.8+0.1
q521.81.8+0.0
q536.66.6+0.1
q545.25.5+0.3
q551.82.0+0.2
q562.72.6-0.1
q5715.715.8+0.0
q583.33.1-0.3
q5913.713.9+0.2
q603.93.9-0.0
q613.33.6+0.3
q629.125.2+16.2
q636.76.8+0.1
q6477.876.6-1.2
q6532.532.5+0.0
q669.18.9-0.2
q67151.2157.3+6.1
q683.43.7+0.3
q693.43.4-0.1
q7010.510.5-0.1
q714.24.7+0.5
q7224.224.1-0.0
q732.62.6+0.0
q7424.324.7+0.3
q7560.962.1+1.1
q7651.052.2+1.2
q773.03.1+0.0
q78154.9159.5+4.6
q797.07.0+0.0
q8022.322.5+0.2
q816.36.6+0.3
q8224.623.7-0.9
q831.71.8+0.1
q847.27.1-0.1
q859.49.3-0.1
q862.92.7-0.2
q8735.634.3-1.3
q8824.223.4-0.8
q896.96.9+0.0
q907.87.4-0.4
q911.81.8+0.0
q921.51.3-0.2
q9393.897.8+4.0
q9428.727.6-1.2
q9525.023.7-1.3
q9622.622.4-0.2
q9737.438.0+0.7
q983.33.1-0.2
q9913.514.0+0.5

Running the benchmark

The cluster runner, the Spark-on-Kubernetes manifests and the image are in the benchmark runner's README. run-matrix.sh writes one JSON-lines result file per run; this page is rendered from them by benchmarks/scripts/render-10tb-page.py. The runs and their memory measurements are discussed in #869.

TPC-DS is a benchmark of the Transaction Processing Performance Council; these results are not audited TPC results and are not comparable to published TPC-DS results. VecRuntime's times are one measured iteration per query. The other engines' totals are their publishers' figures.