Performance

Beats Spark
on the public benchmarks.

Every query. Open methodology. Run it yourself.

ClickBench · c6a.4xlarge · lower is faster
Public
Sail
x1.00
Spark + Gluten/Velox
x5.34
Spark + Auron
x5.61
Apache Spark
x6.36
Spark + Comet
x6.78
ClickBench combined metric (relative time, lower is faster), normalized to Sail = x1.00. Published results in ClickHouse/ClickBench.
10x
Faster than Spark
40x
More data, same cost
98%
Lower infra cost
0
JVM.
PERIOD.
Query-by-Query Breakdown

All 43 queries. Nothing hidden.

ClickBench is a public third-party benchmark for analytical query engines, maintained by the ClickHouse team and open to entries from any system. Forty-three queries against a real-world web analytics dataset. Lower time = faster. Hardware: AWS c6a.4xlarge, single node, Parquet.

9.5x
Median per-query speedup vs Spark
216x
Best single-query speedup (Q7)
2.5x
Worst single-query speedup (Q35)
43 / 43
Queries where Sail leads Spark
Q# Query Sail Spark Speedup
Q1 SELECT COUNT(*) FROM hits 0.014s 2.95s 210.7x
Q2 SELECT COUNT(*) FROM hits WHERE AdvEngineID <> 0 0.044s 3.22s 73.2x
Q3 SELECT SUM(AdvEngineID), COUNT(*), AVG(ResolutionWidth) FROM hits 0.077s 3.37s 43.8x
Q4 SELECT AVG(UserID) FROM hits 0.08s 3.32s 41.5x
Q5 SELECT COUNT(DISTINCT UserID) FROM hits 0.709s 6.64s 9.4x
Q6 SELECT COUNT(DISTINCT SearchPhrase) FROM hits 0.771s 6.61s 8.6x
Q7 SELECT MIN(EventDate), MAX(EventDate) FROM hits 0.015s 3.25s 216.7x
Q8 SELECT AdvEngineID, COUNT(*) FROM hits WHERE AdvEngineID <> 0 GROUP BY AdvEngineID ORDER BY COUNT(*) DESC 0.049s 3.72s 75.9x
Q9 SELECT RegionID, COUNT(DISTINCT UserID) AS u FROM hits GROUP BY RegionID ORDER BY u DESC LIMIT 10 0.918s 7.43s 8.1x
Q10 SELECT RegionID, SUM(AdvEngineID), COUNT(*) AS c, AVG(ResolutionWidth), COUNT(DISTINCT UserID) FROM hits GROUP BY RegionID ORDER BY c DESC LIMIT 10 1.044s 8.34s 8.0x
Q11 SELECT MobilePhoneModel, COUNT(DISTINCT UserID) AS u FROM hits WHERE MobilePhoneModel <> '' GROUP BY MobilePhoneModel ORDER BY u DESC LIMIT 10 0.217s 5.57s 25.7x
Q12 SELECT MobilePhone, MobilePhoneModel, COUNT(DISTINCT UserID) AS u FROM hits WHERE MobilePhoneModel <> '' GROUP BY MobilePhone, MobilePhoneModel ORDER BY u DESC LIMIT 10 0.249s 5.75s 23.1x
Q13 SELECT SearchPhrase, COUNT(*) AS c FROM hits WHERE SearchPhrase <> '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10 0.825s 6.54s 7.9x
Q14 SELECT SearchPhrase, COUNT(DISTINCT UserID) AS u FROM hits WHERE SearchPhrase <> '' GROUP BY SearchPhrase ORDER BY u DESC LIMIT 10 1.189s 9.63s 8.1x
Q15 SELECT SearchEngineID, SearchPhrase, COUNT(*) AS c FROM hits WHERE SearchPhrase <> '' GROUP BY SearchEngineID, SearchPhrase ORDER BY c DESC LIMIT 10 0.828s 6.89s 8.3x
Q16 SELECT UserID, COUNT(*) FROM hits GROUP BY UserID ORDER BY COUNT(*) DESC LIMIT 10 0.855s 6.85s 8.0x
Q17 SELECT UserID, SearchPhrase, COUNT(*) FROM hits GROUP BY UserID, SearchPhrase ORDER BY COUNT(*) DESC LIMIT 10 1.67s 9.37s 5.6x
Q18 SELECT UserID, SearchPhrase, COUNT(*) FROM hits GROUP BY UserID, SearchPhrase LIMIT 10 1.69s 8.02s 4.7x
Q19 SELECT UserID, extract(minute FROM CAST(EventTime AS TIMESTAMP)) AS m, SearchPhrase, COUNT(*) FROM hits GROUP BY UserID, m, SearchPhrase ORDER BY COUNT(*) DESC LIMIT 10 3.268s 14.3s 4.4x
Q20 SELECT UserID FROM hits WHERE UserID = 435090932899640449 0.086s 3.13s 36.4x
Q21 SELECT COUNT(*) FROM hits WHERE URL LIKE '%google%' 1.343s 5.95s 4.4x
Q22 SELECT SearchPhrase, MIN(URL), COUNT(*) AS c FROM hits WHERE URL LIKE '%google%' AND SearchPhrase <> '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10 1.614s 7.26s 4.5x
Q23 SELECT SearchPhrase, MIN(URL), MIN(Title), COUNT(*) AS c, COUNT(DISTINCT UserID) FROM hits WHERE Title LIKE '%Google%' AND URL NOT LIKE '%.google.%' AND SearchPhrase <> '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10 3.531s 9.86s 2.8x
Q24 SELECT * FROM hits WHERE URL LIKE '%google%' ORDER BY EventTime LIMIT 10 10.15s 41.41s 4.1x
Q25 SELECT SearchPhrase FROM hits WHERE SearchPhrase <> '' ORDER BY EventTime LIMIT 10 0.378s 4.39s 11.6x
Q26 SELECT SearchPhrase FROM hits WHERE SearchPhrase <> '' ORDER BY SearchPhrase LIMIT 10 0.268s 4.11s 15.3x
Q27 SELECT SearchPhrase FROM hits WHERE SearchPhrase <> '' ORDER BY EventTime, SearchPhrase LIMIT 10 0.375s 4.48s 11.9x
Q28 SELECT CounterID, AVG(length(URL)) AS l, COUNT(*) AS c FROM hits WHERE URL <> '' GROUP BY CounterID HAVING COUNT(*) > 100000 ORDER BY l DESC LIMIT 25 1.639s 7.84s 4.8x
Q29 SELECT REGEXP_REPLACE(Referer, '^https?://(?:www\.)?([^/]+)/.*$', '\1') AS k, AVG(length(Referer)) AS l, COUNT(*) AS c, MIN(Referer) FROM hits WHERE Referer <> '' GROUP BY k HAVING COUNT(*) > 100000 ORDER BY l DESC LIMIT 25 3.173s 23.59s 7.4x
Q30 SELECT SUM(ResolutionWidth), SUM(ResolutionWidth + 1), … (90 sums) … FROM hits 0.668s 6.72s 10.1x
Q31 SELECT SearchEngineID, ClientIP, COUNT(*) AS c, SUM(IsRefresh), AVG(ResolutionWidth) FROM hits WHERE SearchPhrase <> '' GROUP BY SearchEngineID, ClientIP ORDER BY c DESC LIMIT 10 0.705s 6.52s 9.2x
Q32 SELECT WatchID, ClientIP, COUNT(*) AS c, SUM(IsRefresh), AVG(ResolutionWidth) FROM hits WHERE SearchPhrase <> '' GROUP BY WatchID, ClientIP ORDER BY c DESC LIMIT 10 0.771s 7.3s 9.5x
Q33 SELECT WatchID, ClientIP, COUNT(*) AS c, SUM(IsRefresh), AVG(ResolutionWidth) FROM hits GROUP BY WatchID, ClientIP ORDER BY c DESC LIMIT 10 2.923s 16.7s 5.7x
Q34 SELECT URL, COUNT(*) AS c FROM hits GROUP BY URL ORDER BY c DESC LIMIT 10 4.904s 12.93s 2.6x
Q35 SELECT 1, URL, COUNT(*) AS c FROM hits GROUP BY 1, URL ORDER BY c DESC LIMIT 10 5.028s 12.79s 2.5x
Q36 SELECT ClientIP, ClientIP - 1, ClientIP - 2, ClientIP - 3, COUNT(*) AS c FROM hits GROUP BY ClientIP, ClientIP - 1, ClientIP - 2, ClientIP - 3 ORDER BY c DESC LIMIT 10 0.681s 6.97s 10.2x
Q37 SELECT URL, COUNT(*) AS PageViews FROM hits WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND DontCountHits = 0 AND IsRefresh = 0 AND URL <> '' GROUP BY URL ORDER BY PageViews DESC LIMIT 10 0.231s 3.88s 16.8x
Q38 SELECT Title, COUNT(*) AS PageViews FROM hits WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND DontCountHits = 0 AND IsRefresh = 0 AND Title <> '' GROUP BY Title ORDER BY PageViews DESC LIMIT 10 0.095s 3.66s 38.5x
Q39 SELECT URL, COUNT(*) AS PageViews FROM hits WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND IsRefresh = 0 AND IsLink <> 0 AND IsDownload = 0 GROUP BY URL ORDER BY PageViews DESC LIMIT 10 OFFSET 1000 0.143s 3.7s 25.9x
Q40 SELECT TraficSourceID, SearchEngineID, AdvEngineID, CASE WHEN (SearchEngineID = 0 AND AdvEngineID = 0) THEN Referer ELSE '' END AS Src, URL AS Dst, COUNT(*) AS PageViews FROM hits WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND IsRefresh = 0 GROUP BY TraficSourceID, SearchEngineID, AdvEngineID, Src, Dst ORDER BY PageViews DESC LIMIT 10 OFFSET 1000 0.461s 5.47s 11.9x
Q41 SELECT URLHash, EventDate, COUNT(*) AS PageViews FROM hits WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND IsRefresh = 0 AND TraficSourceID IN (-1, 6) AND RefererHash = 3594120000172545465 GROUP BY URLHash, EventDate ORDER BY PageViews DESC LIMIT 10 OFFSET 100 0.064s 4.01s 62.7x
Q42 SELECT WindowClientWidth, WindowClientHeight, COUNT(*) AS PageViews FROM hits WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND IsRefresh = 0 AND DontCountHits = 0 AND URLHash = 2868770270353813622 GROUP BY WindowClientWidth, WindowClientHeight ORDER BY PageViews DESC LIMIT 10 OFFSET 10000 0.057s 3.87s 67.9x
Q43 SELECT DATE_TRUNC('minute', CAST(EventTime AS TIMESTAMP)) AS M, COUNT(*) AS PageViews FROM hits WHERE CounterID = 62 AND EventDate >= '2013-07-14' AND EventDate <= '2013-07-15' AND IsRefresh = 0 AND DontCountHits = 0 GROUP BY DATE_TRUNC('minute', CAST(EventTime AS TIMESTAMP)) ORDER BY DATE_TRUNC('minute', CAST(EventTime AS TIMESTAMP)) LIMIT 10 OFFSET 1000 0.056s 3.92s 70.0x
single-node · c6a.4xlarge · 14 GB Parquet · published runs
Sail JSON ↗ Spark JSON ↗
Technical Credibility

Verified by people who built the underlying stack.

LakeSail is built on Apache Arrow and Apache DataFusion, the same open-source engine infrastructure that powers a generation of fast analytical systems. The people who built those foundations have reviewed our work.

"

LakeSail embodies the best next generation lakehouse architecture, combining native performance with managed ease of use. A compelling platform for data intensive applications.

Andrew Lamb InfluxData Staff Engineer & Apache DataFusion PMC
Maintains
Why this matters
He helps maintain the engine LakeSail builds on
Andrew Lamb is a core contributor to Apache DataFusion, the vectorized query engine that powers LakeSail's Rust runtime.
Arrow + DataFusion are the foundation
Sail, the open-source engine that powers LakeSail, is built directly on Apache Arrow's columnar memory format and DataFusion's vectorized execution engine. Apache DataFusion tests each of its releases on Sail. Both are ASF projects with thousands of contributors.
Open Methodology

Run it yourself.
Every step is open.

The Sail entry in ClickBench is open and runnable end-to-end. Install script, data loader, queries, and per-run results all live in one directory on GitHub. If you can reproduce a result, you can trust it.

The commands below reproduce the 2026-07-08 c6a.4xlarge Sail run on a fresh Ubuntu host. See benchmark.sh for the canonical flow.

reproduce_clickbench.sh
# Reproduce on AWS c6a.4xlarge, Ubuntu
git clone https://github.com/ClickHouse/ClickBench
cd ClickBench/sail
./install       # Sail + deps (Rust, Python 3.11, pysail)
./load          # no-op: Sail reads hits.parquet directly
./benchmark.sh  # ~14 GB; 43 queries x 3, best of 3 -> result.csv
# Published run: results/20260708/c6a.4xlarge.json
Benchmark environment
Instancec6a.4xlarge
vCPUs16
RAM32 GiB
Datasethits.parquet (~14 GB, 99.99M rows)
Queries43 (all)
Runs3 (best reported)
What the Numbers Mean

From benchmark results
to your actual bill.

Beyond raw speed, the same workload costs dramatically less to run. The numbers below come from a separate derived TPC-H run on a larger dataset, where Sail finished the workload 10x faster and peaked at 26 GB of memory, small enough for an instance 1/4 the size.

Step 1. The benchmark result
10x faster
On a larger dataset than ClickBench, LakeSail's engine completes the full 22-query workload 10x faster than Apache Spark (52.81s vs 534.78s). Every query is faster; the peak per-query speed-up is 29x.
Step 2. Speed becomes time
1/10
Faster execution means your cluster runs for a tenth of the wall-clock time. Combined with LakeSail's engine (which doesn't idle between jobs the way Spark clusters do), active compute time drops sharply.
Step 3. Time becomes cost
Up to 98% lower
Cloud compute is billed for how long you run and how big the instance is. On the derived TPC-H benchmark, Sail finishes in 1/10 the time and its 26 GB memory peak fits an instance 1/4 the size. A tenth of the time on a quarter of the machine is 1/40 the cost, nearly 98% lower.
Step 4. Your workload will vary
Your mileage may differ
Standard benchmarks are not your production environment. Workload mix, query complexity, data volume, and cluster idle patterns all affect your actual savings. The methodology below shows exactly how we derived these numbers.
  • The up to 98% cost reduction is modeled from the derived TPC-H SF100 benchmark (Sail 0.7.0 vs Spark 4.2.0): 1/10 the runtime times 1/4 the instance size is 1/40 the cost, assuming memory is the dominant instance sizing and pricing factor. It is a benchmark-derived model, not a guarantee for all workloads. The 40x more data at the same cost figure is the inverse of the same model.
  • Sail ran with the optimizer.enable_join_reorder option turned on; the Sail configuration marks this option experimental.
  • Benchmark data was generated with tpchgen-cli; the 2024 run used dbgen plus Parquet conversion.
  • Cost is proportional to compute time. LakeSail's stateless workers scale to zero between jobs; Apache Spark clusters typically remain running between jobs, adding idle cost not captured in raw query runtime.
  • Engineering hours (typically 20–40% of total Spark cost) are not included in the compute estimate. That's additional savings not captured in the benchmark number.
  • Raw data and runnable scripts live in the ClickHouse/ClickBench Sail entry on GitHub.
From the field
Building in public forces the kind of transparency and rigor it takes to keep quality high. We're already seeing measurable speedups in our early tests with Sail.
Santosh Pingale Principal Engineer, Data · Adyen | Sail Contributor

Ready to see your numbers?

Book 30 minutes with a LakeSail engineer and see Sail running against your own Spark workloads.