Optimizing DuckDB Against Its Official and Academic Benchmarks

DuckDB development tree, upstream commit e500d7786, branch ks-opt-regex

Benchmarks: TPC-H sf1 · TPC-DS sf1 · IMDB/JOB · h2oai group/join · ClickBench

The branch lives on a local clone of upstream DuckDB and is not yet published; every number below is reproducible from scripts committed on the branch.

Optimized end-to-end by KISS Sorcar on a 32-core x86-64 VM, Ubuntu 24.04, August 2026

What this is about

DuckDB is an in-process analytical database — it plays the role for OLAP workloads that SQLite plays for transactional ones, embedded directly in the host application with no server. This post describes making the current DuckDB development tree faster on five benchmark suites: the two official industry standards that ship with DuckDB’s own benchmark runner (TPC-H at scale factor 1, 22 queries, and TPC-DS at scale factor 1, 99 queries), the academic Join Order Benchmark over the IMDB dataset (113 queries), the h2oai db-benchmark group-by/join suite (15 queries), and ClickBench, a web-log analytics workload (42 queries measured).

The problem

DuckDB is one of the most heavily optimized analytical engines in existence. Its own team lands single-digit-percent wins per operator per release, and the fastest research engine (Umbra) beats it on ClickBench by only about 3–4× on identical hardware, using a fundamentally different architecture built on compiled queries. There is no low-hanging fruit; whatever is gained has to come from real engineering at the margins the DuckDB team has not yet reached, without touching a single benchmark file, query, dataset, or setting.

Profiling did expose one genuine hot spot: ClickBench q28, a REGEXP_REPLACE over roughly 100 million rows, spends 77% of its CPU inside the vendored RE2’s BitState backtracking engine, the path RE2 takes when capture groups are required and its one-pass engine does not apply. Everything else had to come from the build: how the binary is compiled, laid out, and trained.

Measurement itself turned out to be a second problem. Run-to-run drift of up to 30% was measured across sessions on the same machine, large enough to manufacture or hide any realistic gain. Every comparison therefore runs interleaved — baseline and candidate alternate within a single session — and every timed query must first pass DuckDB’s own answer verification, so a wrong result voids the timing.

Summary

Result: verified geometric-mean speedups of 1.152–1.237× per suite over the stock release build, with the largest single-query win at ~1.73× (ClickBench q28). Three of the five suites were held out from all profile training and still improve the most, so the gains generalize rather than memorize. Nothing is broken: the full fast unit-test suite (6,377 tests) shows zero failures attributable to the changes, and ~15,500 adversarial statements plus two randomized fuzz corpora produce byte-identical results against the stock engine.

All of the work (profiling, engine changes, the benchmark harness, adversarial testing, security hardening, and reviews) was carried out by KISS Sorcar, using claude-fable-5 for development, kimi-k3 for security hardening, and gpt-5.6-sol for independent read-only review.

Final measured results

Protocol: baseline and candidate binaries alternate within one session (A,B,A,B), 5 timed runs plus warmup per pass, 10 pooled samples per side, medians compared per query, geometric mean over each suite’s queries. Answers are verified on every run by DuckDB’s own benchmark_runner, and git diff of benchmark/ against upstream is empty — no benchmark file, query, dataset, or setting was modified. ClickBench q24 fails answer verification in the unmodified stock build (a pre-existing upstream nondeterminism with tied ORDER BY rows) and is excluded identically on both sides.

Suite Queries Stock (s) Optimized (s) Geomean speedup
TPC-H sf1 (official) 22 0.540.47 1.152×
TPC-DS sf1 (official) 99 3.142.68 1.184×
IMDB/JOB (academic; held out) 113 9.317.94 1.215×
h2oai group/join (held out) 15 1.891.51 1.234×
ClickBench (held out) 42 1.237×
1.0× 1.1× 1.2× 1.3× TPC-H sf1 1.152× TPC-DS sf1 1.184× IMDB/JOB (held out) 1.215× h2oai (held out) 1.234× ClickBench (held out) 1.237×
Geometric-mean speedup of the optimized stack over the stock release build (interleaved A/B, answers verified, q24 excluded on both sides). Green bars are suites held out from all profile training; they improve the most, which is the opposite of what overfitting would produce.

The notable single-query win is ClickBench q28, the REGEXP_REPLACE query over ~100M rows: ~1.73× in the final stack, 1.79× from the source-level regexp work alone, re-verified at 1.76× after the post-review fix described below.

What was changed

The final stack is three commits on branch ks-opt-regex: source-level regexp changes (d565d7427), a reproducible build pipeline (9fcad94fb), and review fixes with a regression test (04c94c4c4). Each layer was kept only after winning its own interleaved A/B test.

1. BitState self-loop run acceleration (largest single-query gain)

2. regexp_replace fast paths

3. Build pipeline: clang-18, thin-LTO, PGO, BOLT

4. Measured and rejected

How the work was verified

Reproducing the results

The optimized build pipeline is committed on the branch as scripts/ks-optimized-build/, and the interleaved measurement harness lives alongside the clone. The branch is not yet published, so the steps below describe the protocol as it runs locally: start from the same upstream commit, apply the three commits of ks-opt-regex, build, and compare against a stock release build with the interleaved harness.

git clone https://github.com/duckdb/duckdb && cd duckdb
git checkout e500d7786

# apply the three commits of branch ks-opt-regex:
#   d565d7427  regexp/RE2 source optimizations
#   9fcad94fb  scripts/ks-optimized-build/ (reproducible build pipeline)
#   04c94c4c4  review fixes + NULL-validation regression test

scripts/ks-optimized-build/build_optimized.sh   # clang-18 -march=native,
                                                # thin-LTO, 3-stage PGO
scripts/ks-optimized-build/bolt.sh              # BOLT: instrument, train,
                                                # re-layout (ext-tsp)

# interleaved A/B: stock and optimized runners alternate in one session,
# 5 timed runs + warmup per pass, answers verified on every run
harness/ab.sh <stock_runner> <optimized_runner> <suite>

Raw per-query result CSVs from every A/B session are kept next to the harness. PGO and BOLT both retrain during the build, so exact ratios vary a few percent with the machine and the profile; the interleaved protocol exists precisely because single-session absolute times drifted by up to 30% on this hardware. All measurements so far are from one machine class: a 32-core x86-64 VM with 125 GB RAM on Ubuntu 24.04.