Re-measure the single-engine benchmarks on current main (#367) - #374
Conversation
Part of the 1.0-alpha benchmark pass (commandprompt#367). The single-engine sections were one run from 2026-07-27 at commit 7a9c9f7, which predates column projection (commandprompt#339), every vectorized aggregate, and the whole planner and fetch-cache wave. Re-run at eb5c7ef with bench/run_bench.sh unchanged, so the comparison is valid modulo machine and major (PG18.4 here against PG17.10 then). The largest correction is the point lookup. The page described it as an open regression at 1251.88 ms and pointed at commandprompt#171. commandprompt#171 closed on 2026-07-27, the same day the published run was taken, so the page has been reporting a fixed bug as open. It is 15.64 ms now. The filtered aggregate and the projection query each improved about 8x, which is column projection reading only the referenced columns. Arrow and Parquet import improved about 4x. Sorted storage after vacuum_sorted went 47.72 ms to 1.61 ms. Storage sizes are unchanged. The mutation table needs its own note. Its previous single-row figure of 0.22 ms could not be reproduced on this machine with either build. Comparing the two builds directly on one machine gives 162 ms at 7a9c9f7 against 19 ms at eb5c7ef, so the path is faster than it was and the old figure is not a baseline this run failed to meet. The new table also explains why the columnar cost barely moves between one row and 1000: the row group is the unit of the work. The read stream section is not re-measured and now says so. It needs a PG18 built --with-liburing and no such build exists on this machine. Cross-engine numbers are not touched here; they are a separate 100M run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jdatcmd
left a comment
There was a problem hiding this comment.
Approved
Docs-only, CI green after the install-step flake cleared (exit 124 in "Install
PostgreSQL 18", the same package-fetch hang #352 addressed, not your change).
The point-lookup correction is the important part of this PR and it should be
said plainly: docs/benchmarks.md has spent a week telling users a columnar point
lookup costs 1,251.88 ms and inviting them to treat the row as a bug report against
#171, which closed the same day the run was taken. It is 15.64 ms. That is the kind
of stale number that costs a project users who never file anything, and it is a good
argument for the re-measure being an alpha gate rather than a nice-to-have.
The mutation table is the part I would have got wrong. A harness reporting
0.22 ms before and 71.73 ms now, on an unchanged harness, is exactly the shape that
gets transcribed into a regression. Three things you did instead:
- Formed the obvious hypothesis (your own #362/#363 costing the index path out of a
point UPDATE) and disproved it rather than assuming it, with penalty on/off
timings that match. - A/B'd on one machine and one major with only the code differing:
7a9c9f7gives
162/154/171 ms,eb5c7efgives 19/17/20. The path is 8x faster, and the old
plan carries no index-scan node at all, which is the #171-era planner. - Concluded 0.22 ms is unreproducible on this machine with either build and put
that in the page, rather than presenting it as a baseline this run missed.
That is the right handling of a number that cannot be reproduced: say so, in the
document, where the reader is.
Two smaller things worth noting:
- The vectorization speedup shrinking from 2731x to 601x because the baseline
improved is exactly the kind of ratio that looks like a regression in a diff and
is not. Good that the page explains the cause rather than just carrying the new
number. - The read-stream section keeping its old numbers with the reason stated is
better than silently re-running it against a build without--with-liburingand
publishing something that measures nothing.
I have verified the diff carries no em or en dashes, per docs_style.sh.
Merging. The cross-engine section lands as your second commit; ping #367 when the
100M run finishes and I will cut VERSION and [Unreleased].
Commit 2: the cross-engine section, which completes this PR
Citus is measured rather than omitted. The old table dropped it with "Citus was What moved
q2 and q3 are 250x and 188x — column projection, the fetch cache work and the planner q7 went the wrong way, and that is #376368 ms to 44,058 ms. It is not a storage property: the planner declines an index scan Filed as #376, it is mine from #355/#362/#363, and it is on by default. The table Two things the table records rather than hidesTimescaleDB cannot run the parallel arm on this host. Any query that gets a Spill is reported beside every number, per your #358 requirement — and it I nearly wrote "nothing spilled" off the first nineteen cells, which were all the small Not re-measured, and statedThe read-stream section needs a PG18 built
|
What
The single-engine half of the 1.0-alpha benchmark pass (#367). The cross-engine
section is not touched here — that is a separate 100M run which is still going, and
it will land as a second commit on this branch.
Those sections were one run from 2026-07-27 at commit
7a9c9f7. That predatescolumn projection (#339), every vectorized aggregate, and the entire planner and
fetch-cache wave (#350, #353, #354, #357, #359, #361, #362, #363). Re-run at
eb5c7efwithbench/run_bench.shunchanged — verified, no commit touches itbetween the two — so the comparison is valid modulo machine and major.
The correction that matters most
The page described the point lookup as an open regression at 1251.88 ms and
pointed readers at #171 with "treat the row as a bug report".
#171 closed on 2026-07-27 — the same day the published run was taken. So the page
has spent a week telling users that a columnar point lookup costs 1.25 seconds. It is
15.64 ms.
What moved
vacuum_sortedThe ~8x on the filtered aggregate and the projection query is column projection
(#339) reading only referenced columns. The same cause makes the non-vectorized arm
of the vectorization toggle much faster (1392 ms to 270 ms), which shrinks that
speedup from 2731x to 601x — the ratio fell because the baseline got better, and the
page now says so.
The mutation table, which needed investigating rather than transcribing
The harness reported single-row UPDATE at 0.22 ms before and 71.73 ms now, which
reads as a 326x regression on an unchanged harness. It is not one.
UPDATE. Disproven: the UPDATE keeps
Index Scan, and penalty on/off timingsmatch (19-22 against 19-23 ms).
7a9c9f7gives162 / 154 / 171 ms;
eb5c7efgives 19 / 17 / 20 ms. The path is ~8xfaster. On
7a9c9f7the plan carries no index-scan node at all, which is thePoint lookup regressed 23.75 ms to 1251.88 ms once ANALYZE has run, and ANALYZE itself is pathologically slow on some shapes #171-era planner taking a full scan for a point lookup.
now says that rather than presenting it as a baseline this run missed.
The new table also explains the shape a reader will otherwise find odd: the columnar
cost barely moves between one row and 1000, because the row group is the unit of the
work. Heap pays per row; columnar pays per row group.
Not re-measured, and now stated
bench/run_bench_readstream.shneeds a PG18 built--with-liburing. No such buildexists on this machine, so that section keeps its earlier numbers and the preamble
says so instead of letting them read as current.
Style
test/ste_check.pypasses on every user-facing document.🤖 Generated with Claude Code