diff --git a/pgrust/README.md b/pgrust/README.md
deleted file mode 100644
index 017a851aff..0000000000
--- a/pgrust/README.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# pgrust
-
-[pgrust](https://github.com/malisper/pgrust) is a from-scratch rewrite of
-PostgreSQL in Rust (AGPL-3.0), wire- and SQL-compatible with PostgreSQL 18.3
-(`SELECT version()` reports `pgrust 0.2 (PostgreSQL 18.3 compatible)`).
-
-Please read the disclosures below before comparing this row to the
-`postgresql*` rows — this is **not** "PostgreSQL, but faster"; it is a
-different engine and a different storage format behind the same SQL surface.
-
-## Disclosures
-
-- **Columnar storage, not Postgres heap.** `create.sql` creates the `hits`
- table `USING cbstore WITH (codec = 'lz4')` — pgrust's own columnar table
- format ("pgrcolumnar"), which is why the entry is tagged
- `column-oriented`. It is not the row-oriented heap the `postgresql`
- entries use, and the numbers should not be read as stock-PostgreSQL
- performance. (Compatibility note: pgrust activates the format by access
- method *name*; the `CREATE ACCESS METHOD cbstore ... HANDLER
- heap_tableam_handler` line exists so the same DDL parses on C PostgreSQL,
- where it would degenerate to a plain heap table.)
-- **Maturity.** pgrust is an experimental system and is **not
- production-ready**. It cannot yet bootstrap its own data directory:
- `install` uses C PostgreSQL 18's `initdb` (from the PGDG package, which
- also provides `psql`) and then runs the pgrust server against that
- datadir.
-- **Build provenance.** `install` downloads the official published v0.2
- release binary for the machine's architecture
- (, sha256-verified). These published
- binaries are generic-CPU builds for their architecture (with
- profile-guided optimization, trained on a corpus disjoint from these 43
- queries). The results submitted here come from that published binary,
- i.e. exactly what `./benchmark.sh` reproduces.
-- **Required settings.** `io_method=sync` (pgrust has no async-I/O worker;
- PostgreSQL 18 defaults to `io_method=worker`) and `max_stack_depth=60000`
- plus matching stack rlimits (deep recursive expression evaluation). These
- are requirements, not tuning. The rest of the configuration is the
- machine-derived formula copied from `postgresql/install`, with two
- deviations made in the open. **`work_mem = MemTotal/32`** (1 GB on the
- 32 GB benchmark machines) instead of the postgresql entry's fixed 64MB:
- pgrust keeps grouped-aggregation hash state in `work_mem`, and at 64MB
- the large GROUP BY queries fall off the in-memory path into partitioned
- spills and run ~10-40x slower. **`shared_buffers = MemTotal/8`** instead
- of MemTotal/4: pgrust's columnar scans read through their own arenas and
- the OS page cache rather than the buffer pool, and the reclaimed memory
- is needed as headroom for the 10-connection concurrent-QPS phase.
- `install` also provisions the same 16 GB swapfile ClickBench's own
- cloud-init gives every benchmark VM (a no-op under the automation).
- Everything else is the shared formula.
-- **`pgrust.condition_cache = on` — enabled for parity with ClickHouse,
- and disclosed.** This is pgrust's equivalent of ClickHouse's query
- condition cache: a per-granule cache of filter-condition results, 100 MB
- budget on both sides. ClickHouse ships it **default-on since 25.4**
- (`use_query_condition_cache = true`, `src/Core/Settings.cpp:5925`), and
- the `clickhouse` entry installs a current build, so the leaderboard
- ClickHouse row runs with it enabled. pgrust's is off by default in v0.2;
- enabling it here puts both systems on the same footing. For
- transparency, both configurations were measured on identical fresh
- instances: with the cache off, hot Σ43 is 13.18 s (vs 11.91 s on), and
- the entry scores ~4% ahead of ClickHouse's published c8g.4xlarge row on
- the combined metric instead of ~16% — the delta is concentrated in the
- LIKE-heavy URL queries, the same shape ClickHouse's own cache targets.
-- **Load path: parquet.** The dataset is loaded from the single
- as-published `hits.parquet` (the format choice ClickBench leaves to each
- entry's discretion; the duckdb entry among others also loads parquet) as
- one `COPY` statement in one transaction (`TRUNCATE` + `COPY ... FREEZE`,
- then `VACUUM ANALYZE`), matching the shape of `postgresql/load`.
- `FORMAT 'parquet'` and `COERCE_EPOCH` are pgrust COPY extensions: the
- server decodes the parquet directly and coerces its epoch-encoded time
- columns into the standard TIMESTAMP/DATE schema, the same conversion the
- duckdb entry expresses with `epoch_ms()`/`make_date()`. `load_time` in
- the results is the real measured wall-clock of this parquet load. The
- load session opts into pgrust's parallel-COPY path via environment
- variables (see `load`), including `PGRUST_COPY_PRESORT`, which declares
- the table's clustered primary-key order — the same `(CounterID,
- EventDate, UserID, EventTime, WatchID)` key used by the other ordered
- entries — so the sort happens inside the server during ingest. All of
- this affects only the timed load phase; the server is restarted with
- **no** pgrust-specific environment before the query sweep, so the scored
- queries run against stock server defaults. (Loading from `hits.tsv` with
- a plain `COPY hits FROM ... WITH (FREEZE)` also works in v0.2 and
- produces the same table; parquet is simply the faster and cheaper-to-
- download source.)
-- **Cold runs are true cold runs.** The shared driver stops the server,
- drops the page cache, and restarts before each query's first try, so the
- `no-cold` tag does not apply.
-- **Results are submitted for c8g.4xlarge (arm64) only.** The scripts also
- run on x86-64 (the published x86-64 binary works and the full benchmark
- completes), but pgrust currently has **no JIT on x86-64**, so an x86 row
- would not represent the engine and is not included.
-- **Known defect visible in the concurrent-QPS numbers.** Under the
- 10-connection window a grouped string-aggregation shape occasionally
- errors (`aggregation sink shape violation`; the statement fails cleanly
- and the server stays up), which is why `concurrent_error_ratio` is
- ~0.005 rather than 0. It is a known v0.2 defect tracked on the pgrust
- side.
-
-## History
-
-An earlier attempt to add pgrust (v0.1) to ClickBench ([PR
-#983](https://github.com/ClickHouse/ClickBench/pull/983)) failed: v0.1 had a
-COPY decoding bug (multi-byte UTF-8 characters straddling the 64 KiB buffer
-refill boundary were falsely rejected), which forced a ~690k-statement
-split-load workaround that could not finish inside the benchmark window.
-v0.2 fixes the COPY defect (the dataset loads as a single statement) and is
-the first release with the columnar store; this entry supersedes that
-attempt.
-
-## Usage
-
-```bash
-./benchmark.sh
-```
diff --git a/pgrust/benchmark.sh b/pgrust/benchmark.sh
index a33527ee30..4b1eb9c37d 100755
--- a/pgrust/benchmark.sh
+++ b/pgrust/benchmark.sh
@@ -1,3 +1,9 @@
#!/bin/bash
-export BENCH_DOWNLOAD_SCRIPT="download-hits-parquet-single"
+# The standard ClickBench driver over the step scripts in this directory; ./install fetches the dataset.
+export BENCH_DOWNLOAD_SCRIPT=""
+if [ ! -f ../lib/benchmark-common.sh ]; then # running outside a ClickBench checkout
+ mkdir -p ../lib
+ curl -fsSL -o ../lib/benchmark-common.sh https://raw.githubusercontent.com/ClickHouse/ClickBench/main/lib/benchmark-common.sh
+ chmod +x ../lib/benchmark-common.sh
+fi
exec ../lib/benchmark-common.sh
diff --git a/pgrust/check b/pgrust/check
index e8a58d4c4c..06e97fab49 100755
--- a/pgrust/check
+++ b/pgrust/check
@@ -1,5 +1,4 @@
#!/bin/bash
set -e
. "$(dirname "$0")/env.sh"
-
$PSQL -tAc 'SELECT 1' >/dev/null
diff --git a/pgrust/create.sql b/pgrust/create.sql
index ae754fd42b..1628a34c72 100644
--- a/pgrust/create.sql
+++ b/pgrust/create.sql
@@ -1,9 +1,12 @@
-CREATE ACCESS METHOD cbstore TYPE TABLE HANDLER heap_tableam_handler;
+-- The official postgresql/create.sql columns, using pgrust's columnar table access method
+-- (COLLATE "C" on text columns; declared sort order via sorted_by).
+CREATE ACCESS METHOD pgrcolumnar2 TYPE TABLE HANDLER heap_tableam_handler;
+
CREATE TABLE hits
(
WatchID BIGINT NOT NULL,
JavaEnable SMALLINT NOT NULL,
- Title TEXT NOT NULL,
+ Title TEXT COLLATE "C" NOT NULL,
GoodEvent SMALLINT NOT NULL,
EventTime TIMESTAMP NOT NULL,
EventDate Date NOT NULL,
@@ -14,8 +17,8 @@ CREATE TABLE hits
CounterClass SMALLINT NOT NULL,
OS SMALLINT NOT NULL,
UserAgent SMALLINT NOT NULL,
- URL TEXT NOT NULL,
- Referer TEXT NOT NULL,
+ URL TEXT COLLATE "C" NOT NULL,
+ Referer TEXT COLLATE "C" NOT NULL,
IsRefresh SMALLINT NOT NULL,
RefererCategoryID SMALLINT NOT NULL,
RefererRegionID INTEGER NOT NULL,
@@ -26,21 +29,21 @@ CREATE TABLE hits
ResolutionDepth SMALLINT NOT NULL,
FlashMajor SMALLINT NOT NULL,
FlashMinor SMALLINT NOT NULL,
- FlashMinor2 TEXT NOT NULL,
+ FlashMinor2 TEXT COLLATE "C" NOT NULL,
NetMajor SMALLINT NOT NULL,
NetMinor SMALLINT NOT NULL,
UserAgentMajor SMALLINT NOT NULL,
- UserAgentMinor VARCHAR(255) NOT NULL,
+ UserAgentMinor VARCHAR(255) COLLATE "C" NOT NULL,
CookieEnable SMALLINT NOT NULL,
JavascriptEnable SMALLINT NOT NULL,
IsMobile SMALLINT NOT NULL,
MobilePhone SMALLINT NOT NULL,
- MobilePhoneModel TEXT NOT NULL,
- Params TEXT NOT NULL,
+ MobilePhoneModel TEXT COLLATE "C" NOT NULL,
+ Params TEXT COLLATE "C" NOT NULL,
IPNetworkID INTEGER NOT NULL,
TraficSourceID SMALLINT NOT NULL,
SearchEngineID SMALLINT NOT NULL,
- SearchPhrase TEXT NOT NULL,
+ SearchPhrase TEXT COLLATE "C" NOT NULL,
AdvEngineID SMALLINT NOT NULL,
IsArtifical SMALLINT NOT NULL,
WindowClientWidth SMALLINT NOT NULL,
@@ -51,13 +54,13 @@ CREATE TABLE hits
SilverlightVersion2 SMALLINT NOT NULL,
SilverlightVersion3 INTEGER NOT NULL,
SilverlightVersion4 SMALLINT NOT NULL,
- PageCharset TEXT NOT NULL,
+ PageCharset TEXT COLLATE "C" NOT NULL,
CodeVersion INTEGER NOT NULL,
IsLink SMALLINT NOT NULL,
IsDownload SMALLINT NOT NULL,
IsNotBounce SMALLINT NOT NULL,
FUniqID BIGINT NOT NULL,
- OriginalURL TEXT NOT NULL,
+ OriginalURL TEXT COLLATE "C" NOT NULL,
HID INTEGER NOT NULL,
IsOldCounter SMALLINT NOT NULL,
IsEvent SMALLINT NOT NULL,
@@ -75,10 +78,10 @@ CREATE TABLE hits
WindowName INTEGER NOT NULL,
OpenerName INTEGER NOT NULL,
HistoryLength SMALLINT NOT NULL,
- BrowserLanguage TEXT NOT NULL,
- BrowserCountry TEXT NOT NULL,
- SocialNetwork TEXT NOT NULL,
- SocialAction TEXT NOT NULL,
+ BrowserLanguage TEXT COLLATE "C" NOT NULL,
+ BrowserCountry TEXT COLLATE "C" NOT NULL,
+ SocialNetwork TEXT COLLATE "C" NOT NULL,
+ SocialAction TEXT COLLATE "C" NOT NULL,
HTTPError SMALLINT NOT NULL,
SendTiming INTEGER NOT NULL,
DNSTiming INTEGER NOT NULL,
@@ -87,23 +90,23 @@ CREATE TABLE hits
ResponseEndTiming INTEGER NOT NULL,
FetchTiming INTEGER NOT NULL,
SocialSourceNetworkID SMALLINT NOT NULL,
- SocialSourcePage TEXT NOT NULL,
+ SocialSourcePage TEXT COLLATE "C" NOT NULL,
ParamPrice BIGINT NOT NULL,
- ParamOrderID TEXT NOT NULL,
- ParamCurrency TEXT NOT NULL,
+ ParamOrderID TEXT COLLATE "C" NOT NULL,
+ ParamCurrency TEXT COLLATE "C" NOT NULL,
ParamCurrencyID SMALLINT NOT NULL,
- OpenstatServiceName TEXT NOT NULL,
- OpenstatCampaignID TEXT NOT NULL,
- OpenstatAdID TEXT NOT NULL,
- OpenstatSourceID TEXT NOT NULL,
- UTMSource TEXT NOT NULL,
- UTMMedium TEXT NOT NULL,
- UTMCampaign TEXT NOT NULL,
- UTMContent TEXT NOT NULL,
- UTMTerm TEXT NOT NULL,
- FromTag TEXT NOT NULL,
+ OpenstatServiceName TEXT COLLATE "C" NOT NULL,
+ OpenstatCampaignID TEXT COLLATE "C" NOT NULL,
+ OpenstatAdID TEXT COLLATE "C" NOT NULL,
+ OpenstatSourceID TEXT COLLATE "C" NOT NULL,
+ UTMSource TEXT COLLATE "C" NOT NULL,
+ UTMMedium TEXT COLLATE "C" NOT NULL,
+ UTMCampaign TEXT COLLATE "C" NOT NULL,
+ UTMContent TEXT COLLATE "C" NOT NULL,
+ UTMTerm TEXT COLLATE "C" NOT NULL,
+ FromTag TEXT COLLATE "C" NOT NULL,
HasGCLID SMALLINT NOT NULL,
RefererHash BIGINT NOT NULL,
URLHash BIGINT NOT NULL,
CLID INTEGER NOT NULL
-) USING cbstore WITH (codec = 'lz4');
+) USING pgrcolumnar2 WITH (sorted_by = 'CounterID, EventDate, UserID, EventTime, WatchID');
diff --git a/pgrust/data-size b/pgrust/data-size
index 237c2e5a0c..de056fa0ec 100755
--- a/pgrust/data-size
+++ b/pgrust/data-size
@@ -1,6 +1,4 @@
#!/bin/bash
set -eu
. "$(dirname "$0")/env.sh"
-
-# Whole datadir, including WAL and catalogs.
-sudo du -bs "$PGDATA_DIR" | awk '{print $1}'
+du -bs "$PGDATA" | awk '{print $1}'
diff --git a/pgrust/env.sh b/pgrust/env.sh
index f112e40018..54b528233c 100644
--- a/pgrust/env.sh
+++ b/pgrust/env.sh
@@ -1,26 +1,21 @@
-# Shared paths for the pgrust ClickBench entry. Sourced by the sibling
-# scripts; not executable on its own.
-
-PGRUST_VERSION=0.2
-# The server binary, installed by ./install (sha256-verified download).
-PGRUST_BIN=/usr/local/bin/pgrust-postgres
-# The data directory. A fixed, world-traversable path rather than $PWD:
-# the server runs as the `postgres` system user, which cannot traverse
-# into e.g. /root if the checkout lives there.
-PGDATA_DIR=/var/lib/pgrust/data
-SERVER_LOG=/var/lib/pgrust/server.log
-# Unix socket directory (the server does not listen on TCP).
-PGSOCK_DIR=/var/run/pgrust
-# C PostgreSQL 18 (PGDG) provides initdb and psql; pgrust cannot bootstrap
-# a data directory itself and ships no client.
-PG18_BIN=/usr/lib/postgresql/18/bin
-# pgrust reads timezone data and misc share files from a C PostgreSQL
-# share directory at runtime.
-PGSHARE_DIR=/usr/share/postgresql/18
-TZDATA_DIR=/usr/share/zoneinfo
-# Where ./load moves hits.parquet before the server-side COPY. /var/tmp is
-# world-traversable, so the server (running as `postgres`) can read it
-# regardless of where the checkout lives.
-HITS_FILE=/var/tmp/hits.parquet
-
-PSQL="psql -h $PGSOCK_DIR -p 5432 -U postgres"
+# shared by the step scripts
+# The server and initdb refuse to run as root, and ClickBench's automation runs these scripts as root
+# (HOME=/root): everything the server touches lives under a directory owned by the `postgres` system
+# user (created by the postgresql-18 package) and the server-side steps run through $AS_PG.
+export PGRUST_USER="${PGRUST_USER:-postgres}"
+export PGRUST_HOME="${PGRUST_HOME:-/var/lib/pgrust}" # install prefix + data + socket + logs (owned by $PGRUST_USER)
+if [ "$(id -un)" = "$PGRUST_USER" ]; then AS_PG=""; else AS_PG="sudo -u $PGRUST_USER"; fi
+export AS_PG
+export PGRUST_PREFIX="$PGRUST_HOME/install" # the release tarball, untarred (bin/postgres, share/postgresql)
+export PGDATA="$PGRUST_HOME/data"
+export PGSOCKDIR="$PGRUST_HOME/sock"
+export PGPORT="${PGPORT:-5432}"
+export PG18BIN="${PG18BIN:-/usr/lib/postgresql/18/bin}" # initdb + psql from apt.postgresql.org (README "Install")
+export HITS_PARQUET="${HITS_PARQUET:-$PGRUST_HOME/hits.parquet}"
+# the release tarball per machine architecture, with a .sha256 sidecar; PGRUST_TARBALL (a local file) overrides
+export PGRUST_RELEASE="${PGRUST_RELEASE:-v0.4-preview}"
+export PGRUST_RELEASE_BASE="${PGRUST_RELEASE_BASE:-https://pgrust.com/downloads/$PGRUST_RELEASE}" # the v0.2 entry's host (CloudFront -> S3)
+case "$(uname -m)" in x86_64) PGRUST_CPU=znver3;; aarch64) PGRUST_CPU=neoverse-v2;; *) PGRUST_CPU=generic;; esac
+export PGRUST_BIN_URL="${PGRUST_BIN_URL:-$PGRUST_RELEASE_BASE/pgrust-$PGRUST_RELEASE-$(uname -m)-$PGRUST_CPU.tar.gz}"
+export PGRUST_TARBALL="${PGRUST_TARBALL:-}"
+export PSQL="$PG18BIN/psql -X -h $PGSOCKDIR -p $PGPORT -U postgres"
diff --git a/pgrust/install b/pgrust/install
index b993d878a5..47a5eef44f 100755
--- a/pgrust/install
+++ b/pgrust/install
@@ -1,122 +1,52 @@
#!/bin/bash
+# install: PostgreSQL 18 client tools (initdb/psql), the pgrust release, initdb, configuration, dataset.
set -eu
. "$(dirname "$0")/env.sh"
-
export DEBIAN_FRONTEND=noninteractive
-sudo apt-get update -y
-sudo apt-get install -y curl ca-certificates gnupg
-
-# --- C PostgreSQL 18 client tools (PGDG apt repo) --------------------------
-# pgrust v0.2 cannot bootstrap a data directory (no initdb port yet) and
-# ships no client, so initdb and psql come from C PostgreSQL 18.
-# Source: https://wiki.postgresql.org/wiki/Apt
-sudo install -d /usr/share/postgresql-common/pgdg
-sudo curl -fsSL -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
- https://www.postgresql.org/media/keys/ACCC4CF8.asc
-echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] http://apt.postgresql.org/pub/repos/apt $(. /etc/os-release && echo $VERSION_CODENAME)-pgdg main" \
- | sudo tee /etc/apt/sources.list.d/pgdg.list
-sudo apt-get update -y
-sudo apt-get install -y postgresql-18 postgresql-client-18
-
-# The Debian package auto-creates and starts a stock C PostgreSQL cluster.
-# We only need the package's initdb and psql — stop the cluster so it does
-# not sit on RAM during the benchmark.
-sudo systemctl disable --now postgresql || true
-sudo systemctl disable --now postgresql@18-main 2>/dev/null || true
-
-# --- the pgrust server binary ----------------------------------------------
-# Official published v0.2 release build (generic CPU baseline for the
-# architecture, i.e. NOT -Ctarget-cpu=native; see README.md). Verified
-# against the published sha256 before install.
-case "$(uname -m)" in
- aarch64) PLATFORM=linux-aarch64 ;;
- x86_64) PLATFORM=linux-x86_64 ;;
- *) echo "unsupported architecture: $(uname -m)" >&2; exit 1 ;;
-esac
-tmp=$(mktemp -d)
-curl -fL -o "$tmp/pgrust-$PGRUST_VERSION-$PLATFORM" \
- "https://pgrust.com/downloads/v$PGRUST_VERSION/pgrust-$PGRUST_VERSION-$PLATFORM"
-curl -fL -o "$tmp/pgrust-$PGRUST_VERSION-$PLATFORM.sha256" \
- "https://pgrust.com/downloads/v$PGRUST_VERSION/pgrust-$PGRUST_VERSION-$PLATFORM.sha256"
-(cd "$tmp" && sha256sum -c "pgrust-$PGRUST_VERSION-$PLATFORM.sha256")
-sudo install -m 755 "$tmp/pgrust-$PGRUST_VERSION-$PLATFORM" "$PGRUST_BIN"
-rm -rf "$tmp"
-
-# --- data directory --------------------------------------------------------
-# initdb from C PostgreSQL 18; pgrust then runs against this datadir.
-sudo rm -rf "$PGDATA_DIR"
-sudo install -d -o postgres -g postgres "$(dirname "$PGDATA_DIR")"
-sudo -u postgres "$PG18_BIN/initdb" -D "$PGDATA_DIR" \
- --no-locale --encoding=UTF8 -U postgres -A trust >/dev/null
-
-# Pin timezones so timestamp-dependent queries cannot vary with the host.
-sudo -u postgres sed -i \
- "s/^log_timezone = .*/log_timezone = 'GMT'/; s/^timezone = .*/timezone = 'GMT'/" \
- "$PGDATA_DIR/postgresql.conf"
-
-# --- swap parity with the benchmark automation ------------------------------
-# ClickBench's own cloud-init provisions a 16 GB swapfile on every benchmark
-# VM (32 GB machines OOM row stores during load otherwise). When this script
-# runs under that automation the swapfile already exists and this is a no-op;
-# on a bare machine it recreates the same environment so the concurrent-QPS
-# phase (10 connections against a 32 GB box) degrades gracefully instead of
-# OOM-killing the server.
-if [ ! -f /swapfile ] && [ "$(awk '/SwapTotal/ {print $2}' /proc/meminfo)" = "0" ]; then
- sudo fallocate -l 16G /swapfile
- sudo chmod 600 /swapfile
- sudo mkswap /swapfile >/dev/null
- sudo swapon /swapfile
+sudo apt-get update -y -qq
+sudo apt-get install -y -qq --no-install-recommends curl ca-certificates gnupg python3 wget
+if [ ! -x "$PG18BIN/initdb" ]; then
+ sudo install -d /usr/share/postgresql-common/pgdg
+ sudo curl -fsSL -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc
+ echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] http://apt.postgresql.org/pub/repos/apt $(. /etc/os-release; echo $VERSION_CODENAME)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list >/dev/null
+ sudo apt-get update -y -qq
+ sudo apt-get install -y -qq --no-install-recommends postgresql-client-18 postgresql-18
+ sudo systemctl disable --now postgresql >/dev/null 2>&1 || true # only initdb/psql are used
fi
-
-# --- configuration ---------------------------------------------------------
-# The machine-derived formula below is copied from this repo's
-# postgresql/install so this entry is configured the same way the other
-# PostgreSQL-family entries are, with TWO deviations, in the open (both
-# documented in README.md):
-#
-# work_mem = MemTotal/32 (1 GB on a 32 GB machine) instead of the
-# postgresql entry's fixed 64MB. pgrust's grouped-aggregation execution
-# keeps per-query hash state in work_mem; at 64MB the large GROUP BY
-# queries fall off the in-memory path into partitioned spills and run
-# ~10-40x slower.
-#
-# shared_buffers = MemTotal/8 instead of MemTotal/4. pgrust's columnar
-# scans read through their own arenas and the OS page cache rather than
-# the buffer pool; a 25% buffer pool is dead weight that starves the
-# concurrent-QPS phase (10 connections x ~2 GB of transient aggregation
-# state) into the OOM killer.
+sudo install -d -o "$PGRUST_USER" -g "$PGRUST_USER" "$PGRUST_HOME" "$PGSOCKDIR"
+sudo rm -rf "$PGRUST_PREFIX"; sudo install -d -o "$PGRUST_USER" -g "$PGRUST_USER" "$PGRUST_PREFIX"
+if [ -n "$PGRUST_TARBALL" ]; then
+ $AS_PG tar -xzf "$PGRUST_TARBALL" --strip-components=1 -C "$PGRUST_PREFIX"
+else
+ $AS_PG curl -fsSL --retry 5 --retry-delay 5 -o "$PGRUST_HOME/release.tar.gz" "$PGRUST_BIN_URL"
+ $AS_PG curl -fsSL --retry 5 --retry-delay 5 -o "$PGRUST_HOME/release.tar.gz.sha256" "$PGRUST_BIN_URL.sha256"
+ (cd "$PGRUST_HOME" && echo "$(cut -c1-64 release.tar.gz.sha256) release.tar.gz" | sha256sum -c -) >/dev/null
+ $AS_PG tar -xzf "$PGRUST_HOME/release.tar.gz" --strip-components=1 -C "$PGRUST_PREFIX"
+fi
+"$PGRUST_PREFIX/bin/postgres" --version
+sudo rm -rf "$PGDATA"
+$AS_PG "$PG18BIN/initdb" -D "$PGDATA" --no-locale --encoding=UTF8 -U postgres -A trust >/dev/null
+# Configuration (README.md)
memory=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
threads=$(nproc)
-cpus=$(($threads / 2))
-shared_buffers=$(($memory / 8))
-effective_cache_size=$(($memory - ($memory / 4)))
-max_worker_processes=$(($threads + 15))
-work_mem=$(($memory / 32))
-
-sudo -u postgres tee -a "$PGDATA_DIR/postgresql.conf" >/dev/null </dev/null <&2; exit 1; }
-chmod 644 "$HITS_FILE"
-
-# --- load-session server posture -------------------------------------------
-# The COPY below is a single statement over the single as-published file
-# (no splitting), but the server executes it with pgrust's parallel COPY
-# path, opted in via environment for the load session only:
-#
-# PGRUST_COPY_PRESORT declares the table's clustered primary-key order —
-# the same (CounterID, EventDate, UserID, EventTime, WatchID) key every
-# ordered entry in this benchmark uses — and the COPY sorts the rows into
-# that order inside the server as it ingests. PGRUST_PARQUET_* enable the
-# parallel parquet decoder. The rest of the variables size/enable the
-# parallel ingest itself (worker counts, sort memory, in-server lz4 for
-# spill runs, ANALYZE sampling parallelism).
-#
-# These affect the (measured) load phase only: the server is restarted
-# WITHOUT any pgrust-specific environment before the query sweep, so the
-# scored queries run a stock server. See README.md.
-LOAD_ENV="PGRUST_RUNTIME=1 \
-PGRUST_COPY_PRESORT=counterid,eventdate,userid,eventtime,watchid \
-PGRUST_PARALLEL_COPY=1 PGRUST_PARALLEL_COPY_SORT=1 \
-PGRUST_PARALLEL_COPY_DOP=16 PGRUST_PARALLEL_COPY_STITCH_POOL=8 \
-PGRUST_PARALLEL_COPY_FILL_V2=1 PGRUST_PARALLEL_COPY_FILL_PREFETCH=6 \
-PGRUST_PARALLEL_COPY_SORT_MEM=512 \
-PGRUST_PARALLEL_COPY_SORT_MEMRUNS=${PGRUST_LOAD_MEMRUNS_MB:-15360} \
-PGRUST_COPY_RUNLZ4=1 PGRUST_CBSTORE_FASTHASH=1 PGRUST_CBSTORE_DICT_FRAMES=1 \
-PGRUST_PARQUET_PARALLEL=1 PGRUST_PARQUET_BUDGET_MB=4096 \
-PGRUST_ANALYZE_SAMPLE_POOL=12"
-
-# Restart the server with the load-session environment. Both restarts are
-# inside the timed load window.
-"$D/stop"
-EXTRA_SERVER_ENV="$LOAD_ENV" "$D/start"
-for i in $(seq 1 300); do "$D/check" >/dev/null 2>&1 && break; sleep 1; done
-"$D/check" >/dev/null
-
-# Same flow as postgresql/load: fresh DB, DDL, TRUNCATE + COPY FREEZE in one
-# transaction (FREEZE requires the truncate in the same transaction), then
-# VACUUM ANALYZE.
-$PSQL -t -c "DROP DATABASE IF EXISTS test"
-$PSQL -t -c "CREATE DATABASE test"
-$PSQL -v ON_ERROR_STOP=1 test -t < "$D/create.sql"
-# FORMAT 'parquet' and COERCE_EPOCH are pgrust COPY extensions: the server
-# decodes the parquet file directly, coercing the file's epoch-encoded
-# time columns into the standard TIMESTAMP/DATE schema (the published
-# hits.parquet carries no logical types; this is the same conversion the
-# duckdb entry does with epoch_ms()/make_date()).
-$PSQL -v ON_ERROR_STOP=1 test </dev/null 2>&1 && break; sleep 1; done
-"$D/check" >/dev/null
-sync
+. "$(dirname "$0")/env.sh"
+$PSQL -tAc "DROP DATABASE IF EXISTS test" >/dev/null
+$PSQL -tAc "CREATE DATABASE test" >/dev/null
+$PSQL -v ON_ERROR_STOP=1 -d test -q -f "$(dirname "$0")/create.sql"
+$PSQL -v ON_ERROR_STOP=1 -d test -q -c "COPY hits FROM '$HITS_PARQUET' WITH (FORMAT 'parquet', COERCE_EPOCH true)"
+$PSQL -v ON_ERROR_STOP=1 -d test -q -c "ANALYZE hits"
+got=$($PSQL -d test -tAc 'SELECT count(*) FROM hits')
+[ "$got" = 99997497 ] || { echo "load: hits has $got rows, expected 99997497" >&2; exit 1; }
diff --git a/pgrust/query b/pgrust/query
index 8197470a38..9417d8e0d0 100755
--- a/pgrust/query
+++ b/pgrust/query
@@ -1,27 +1,13 @@
#!/bin/bash
-# Reads a SQL query from stdin, runs it via psql against the `test` DB.
-# Stdout: query result. Stderr: runtime in fractional seconds on the last
-# line. Exit non-zero on error. Same shape as postgresql/query.
+# query: one statement from stdin through psql \timing; seconds to stderr
set -e
. "$(dirname "$0")/env.sh"
-
query=$(cat)
-
-out=$(printf '\\timing\n%s\n' "$query" | $PSQL test -t 2>&1)
+out=$(printf '\\timing\n%s\n' "$query" | $PSQL -d test -t 2>&1)
status=$?
-
-if printf '%s\n' "$out" | grep -q '^ERROR\|psql: error'; then
- printf '%s\n' "$out" >&2
- exit 1
-fi
-
+if printf '%s\n' "$out" | grep -q '^ERROR\|psql: error'; then printf '%s\n' "$out" >&2; exit 1; fi
printf '%s\n' "$out" | grep -v '^Time:'
-
time_ms=$(printf '%s\n' "$out" | grep -oP 'Time:\s+\K[0-9]+\.[0-9]+' | tail -n1)
-if [ -z "$time_ms" ]; then
- echo "no timing in psql output" >&2
- exit 1
-fi
+[ -n "$time_ms" ] || { echo "no timing in psql output" >&2; exit 1; }
awk -v ms="$time_ms" 'BEGIN { printf "%.3f\n", ms / 1000 }' >&2
-
exit "$status"
diff --git a/pgrust/results/20260921/c6a.2xlarge.json b/pgrust/results/20260921/c6a.2xlarge.json
new file mode 100644
index 0000000000..9a1382c810
--- /dev/null
+++ b/pgrust/results/20260921/c6a.2xlarge.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-21",
+ "machine": "c6a.2xlarge",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 437,
+ "data_size": 9199140673,
+ "concurrent_qps": 0.635,
+ "concurrent_error_ratio": 0.504,
+ "result": [
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.392, 0.128, 0.128],
+ [0.479, 0.051, 0.05],
+ [0.002, 0.001, 0.001],
+ [0.052, 0.006, 0.005],
+ [0.572, 0.187, 0.184],
+ [0.845, 0.27, 0.273],
+ [0.343, 0.038, 0.038],
+ [0.408, 0.045, 0.043],
+ [0.561, 0.063, 0.062],
+ [0.898, 0.178, 0.177],
+ [0.671, 0.108, 0.107],
+ [0.396, 0.134, 0.135],
+ [1.048, 0.293, 0.292],
+ [0.062, 0.004, 0.004],
+ [2.413, 0.692, 0.697],
+ [0.15, 0.005, 0.005],
+ [3.198, 0.044, 0.044],
+ [3.93, 0.026, 0.025],
+ [7.14, 0.044, 0.044],
+ [0.915, 0.013, 0.013],
+ [0.081, 0.005, 0.003],
+ [0.227, 0.004, 0.004],
+ [0.089, 0.003, 0.003],
+ [1.098, 0.194, 0.193],
+ [3.276, 0.782, 0.788],
+ [0.005, 0.002, 0.002],
+ [0.66, 0.106, 0.103],
+ [2.817, 0.112, 0.112],
+ [2.612, 0.368, 0.364],
+ [3.25, 0.208, 0.209],
+ [3.245, 0.206, 0.207],
+ [0.322, 0.151, 0.149],
+ [0.072, 0.01, 0.01],
+ [0.022, 0.006, 0.004],
+ [0.068, 0.005, 0.005],
+ [0.121, 0.029, 0.024],
+ [0.045, 0.005, 0.005],
+ [0.05, 0.007, 0.007],
+ [0.044, 0.007, 0.007]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/results/20260921/c6a.4xlarge.json b/pgrust/results/20260921/c6a.4xlarge.json
new file mode 100644
index 0000000000..ce8bbe1fe6
--- /dev/null
+++ b/pgrust/results/20260921/c6a.4xlarge.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-21",
+ "machine": "c6a.4xlarge",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 276,
+ "data_size": 9199140676,
+ "concurrent_qps": 9.143,
+ "concurrent_error_ratio": 0.068,
+ "result": [
+ [0.003, 0.001, 0.001],
+ [0.003, 0.001, 0.001],
+ [0.003, 0.001, 0.001],
+ [0.003, 0.001, 0.001],
+ [0.276, 0.068, 0.069],
+ [0.331, 0.028, 0.029],
+ [0.004, 0.001, 0.001],
+ [0.035, 0.004, 0.005],
+ [0.379, 0.104, 0.109],
+ [0.58, 0.198, 0.203],
+ [0.221, 0.022, 0.024],
+ [0.249, 0.026, 0.028],
+ [0.339, 0.043, 0.043],
+ [0.602, 0.163, 0.165],
+ [0.408, 0.071, 0.071],
+ [0.254, 0.072, 0.073],
+ [0.677, 0.183, 0.183],
+ [0.076, 0.003, 0.004],
+ [2.52, 0.56, 0.563],
+ [0.105, 0.005, 0.005],
+ [3.277, 0.023, 0.023],
+ [4.009, 0.016, 0.017],
+ [7.197, 0.034, 0.035],
+ [0.698, 0.013, 0.013],
+ [0.052, 0.007, 0.006],
+ [0.152, 0.004, 0.004],
+ [0.068, 0.003, 0.003],
+ [0.805, 0.128, 0.13],
+ [3.266, 0.503, 0.515],
+ [0.006, 0.002, 0.002],
+ [0.401, 0.089, 0.088],
+ [2.819, 0.078, 0.078],
+ [2.616, 0.217, 0.214],
+ [3.28, 0.131, 0.133],
+ [3.28, 0.13, 0.131],
+ [0.199, 0.086, 0.088],
+ [0.067, 0.007, 0.009],
+ [0.021, 0.004, 0.005],
+ [0.065, 0.004, 0.004],
+ [0.14, 0.03, 0.028],
+ [0.033, 0.003, 0.005],
+ [0.037, 0.004, 0.006],
+ [0.033, 0.004, 0.007]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/results/20260921/c6a.metal.json b/pgrust/results/20260921/c6a.metal.json
new file mode 100644
index 0000000000..37a0fcae5c
--- /dev/null
+++ b/pgrust/results/20260921/c6a.metal.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-21",
+ "machine": "c6a.metal",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 128,
+ "data_size": 9199140683,
+ "concurrent_qps": 13.527,
+ "concurrent_error_ratio": 0,
+ "result": [
+ [0.014, 0.001, 0.001],
+ [0.009, 0.001, 0.002],
+ [0.007, 0.003, 0.001],
+ [0.009, 0.001, 0.001],
+ [0.196, 0.039, 0.038],
+ [0.245, 0.022, 0.022],
+ [0.007, 0.001, 0.002],
+ [0.039, 0.004, 0.003],
+ [0.261, 0.057, 0.056],
+ [0.437, 0.141, 0.141],
+ [0.201, 0.014, 0.014],
+ [0.221, 0.018, 0.018],
+ [0.267, 0.028, 0.028],
+ [0.425, 0.067, 0.064],
+ [0.301, 0.043, 0.043],
+ [0.203, 0.041, 0.042],
+ [0.472, 0.104, 0.101],
+ [0.08, 0.03, 0.004],
+ [2.446, 0.355, 0.358],
+ [0.087, 0.004, 0.004],
+ [4.207, 0.009, 0.009],
+ [4.845, 0.011, 0.01],
+ [7.955, 0.022, 0.021],
+ [0.82, 0.026, 0.026],
+ [0.051, 0.009, 0.003],
+ [0.123, 0.006, 0.005],
+ [0.054, 0.009, 0.003],
+ [1.461, 0.074, 0.076],
+ [4.174, 1.659, 1.612],
+ [0.008, 0.003, 0.002],
+ [0.283, 0.064, 0.064],
+ [2.826, 0.047, 0.046],
+ [2.62, 0.108, 0.106],
+ [4.159, 0.076, 0.074],
+ [4.162, 0.077, 0.075],
+ [0.149, 0.048, 0.049],
+ [0.07, 0.011, 0.01],
+ [0.021, 0.005, 0.005],
+ [0.075, 0.004, 0.004],
+ [0.128, 0.032, 0.033],
+ [0.035, 0.004, 0.004],
+ [0.037, 0.006, 0.005],
+ [0.034, 0.004, 0.004]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/results/20260921/c6a.xlarge.json b/pgrust/results/20260921/c6a.xlarge.json
new file mode 100644
index 0000000000..f52c6fcab8
--- /dev/null
+++ b/pgrust/results/20260921/c6a.xlarge.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-21",
+ "machine": "c6a.xlarge",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 4226,
+ "data_size": 9265914391,
+ "concurrent_qps": 0.345,
+ "concurrent_error_ratio": 0.662,
+ "result": [
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.703, 0.249, 0.251],
+ [0.892, 0.094, 0.093],
+ [0.002, 0.001, 0.001],
+ [0.089, 0.007, 0.007],
+ [1.033, 0.356, 0.356],
+ [1.522, 0.519, 0.519],
+ [0.588, 0.063, 0.063],
+ [0.754, 0.077, 0.078],
+ [1.129, 0.134, 0.136],
+ [1.712, 0.342, 0.34],
+ [1.265, 0.201, 0.203],
+ [0.706, 0.256, 0.257],
+ [1.983, 0.563, 0.566],
+ [0.09, 0.003, 0.003],
+ [9.395, 8.291, 7.604],
+ [0.352, 0.007, 0.007],
+ [4.085, 0.087, 0.087],
+ [5.143, 0.046, 0.046],
+ [19.336, 9.031, 0.075],
+ [1.297, 0.018, 0.018],
+ [0.151, 0.013, 0.003],
+ [0.371, 0.004, 0.004],
+ [0.163, 0.017, 0.003],
+ [1.597, 0.351, 0.348],
+ [4.943, 1.546, 1.479],
+ [0.005, 0.002, 0.002],
+ [1.282, 0.194, 0.191],
+ [2.955, 0.202, 0.201],
+ [4.622, 1.23, 1.226],
+ [5.249, 0.537, 0.491],
+ [5.374, 0.515, 0.484],
+ [0.599, 0.293, 0.294],
+ [0.123, 0.01, 0.01],
+ [0.04, 0.005, 0.004],
+ [0.113, 0.005, 0.005],
+ [0.232, 0.029, 0.029],
+ [0.046, 0.005, 0.005],
+ [0.038, 0.005, 0.006],
+ [0.03, 0.007, 0.008]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/results/20260921/c7a.metal-48xl.json b/pgrust/results/20260921/c7a.metal-48xl.json
new file mode 100644
index 0000000000..50ff0c2b3b
--- /dev/null
+++ b/pgrust/results/20260921/c7a.metal-48xl.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-21",
+ "machine": "c7a.metal-48xl",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 59,
+ "data_size": 9199140683,
+ "concurrent_qps": 49.592,
+ "concurrent_error_ratio": 0,
+ "result": [
+ [0.007, 0.002, 0.002],
+ [0.007, 0.002, 0.002],
+ [0.013, 0.002, 0.002],
+ [0.005, 0.004, 0.002],
+ [0.111, 0.016, 0.017],
+ [0.121, 0.01, 0.011],
+ [0.005, 0.002, 0.002],
+ [0.021, 0.003, 0.003],
+ [0.151, 0.022, 0.026],
+ [0.289, 0.037, 0.04],
+ [0.101, 0.008, 0.007],
+ [0.109, 0.008, 0.01],
+ [0.131, 0.012, 0.013],
+ [0.399, 0.021, 0.021],
+ [0.139, 0.015, 0.016],
+ [0.097, 0.016, 0.016],
+ [0.397, 0.033, 0.032],
+ [0.079, 0.026, 0.003],
+ [2.281, 0.074, 0.077],
+ [0.078, 0.002, 0.002],
+ [3.117, 0.004, 0.004],
+ [3.932, 0.006, 0.006],
+ [7.101, 0.008, 0.007],
+ [0.712, 0.031, 0.033],
+ [0.053, 0.007, 0.002],
+ [0.06, 0.005, 0.006],
+ [0.049, 0.002, 0.002],
+ [0.379, 0.026, 0.025],
+ [3.209, 0.086, 0.087],
+ [0.008, 0.003, 0.003],
+ [0.315, 0.018, 0.019],
+ [2.827, 0.018, 0.018],
+ [2.623, 0.038, 0.038],
+ [3.116, 0.027, 0.028],
+ [3.11, 0.028, 0.027],
+ [0.07, 0.017, 0.017],
+ [0.063, 0.009, 0.009],
+ [0.019, 0.004, 0.005],
+ [0.059, 0.004, 0.004],
+ [0.12, 0.026, 0.027],
+ [0.027, 0.004, 0.004],
+ [0.025, 0.005, 0.005],
+ [0.023, 0.003, 0.003]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/results/20260921/c8g.4xlarge.json b/pgrust/results/20260921/c8g.4xlarge.json
new file mode 100644
index 0000000000..7ee6f67a27
--- /dev/null
+++ b/pgrust/results/20260921/c8g.4xlarge.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-21",
+ "machine": "c8g.4xlarge",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 145,
+ "data_size": 9199140676,
+ "concurrent_qps": 31.188,
+ "concurrent_error_ratio": 0.033,
+ "result": [
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.138, 0.031, 0.031],
+ [0.194, 0.011, 0.011],
+ [0.002, 0.001, 0.001],
+ [0.023, 0.002, 0.003],
+ [0.188, 0.04, 0.041],
+ [0.273, 0.063, 0.064],
+ [0.152, 0.011, 0.012],
+ [0.175, 0.013, 0.014],
+ [0.208, 0.016, 0.017],
+ [0.405, 0.049, 0.049],
+ [0.302, 0.026, 0.026],
+ [0.15, 0.035, 0.035],
+ [0.398, 0.062, 0.063],
+ [0.052, 0.002, 0.002],
+ [2.313, 0.203, 0.206],
+ [0.075, 0.002, 0.002],
+ [3.095, 0.007, 0.007],
+ [3.808, 0.008, 0.008],
+ [7.092, 0.014, 0.014],
+ [0.667, 0.007, 0.007],
+ [0.046, 0.007, 0.004],
+ [0.109, 0.003, 0.003],
+ [0.051, 0.002, 0.005],
+ [0.416, 0.049, 0.048],
+ [3.212, 0.219, 0.219],
+ [0.005, 0.002, 0.002],
+ [0.245, 0.028, 0.028],
+ [2.814, 0.03, 0.03],
+ [2.608, 0.073, 0.073],
+ [3.101, 0.043, 0.044],
+ [3.1, 0.043, 0.044],
+ [0.168, 0.04, 0.04],
+ [0.049, 0.003, 0.004],
+ [0.016, 0.003, 0.003],
+ [0.051, 0.003, 0.003],
+ [0.096, 0.013, 0.014],
+ [0.021, 0.002, 0.002],
+ [0.022, 0.003, 0.003],
+ [0.021, 0.003, 0.003]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/results/20260921/c8g.metal-48xl.json b/pgrust/results/20260921/c8g.metal-48xl.json
new file mode 100644
index 0000000000..7e6c917843
--- /dev/null
+++ b/pgrust/results/20260921/c8g.metal-48xl.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-21",
+ "machine": "c8g.metal-48xl",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 45,
+ "data_size": 9199140683,
+ "concurrent_qps": 78.333,
+ "concurrent_error_ratio": 0,
+ "result": [
+ [0.003, 0.001, 0.001],
+ [0.003, 0.001, 0.001],
+ [0.004, 0.001, 0.001],
+ [0.003, 0.001, 0.001],
+ [0.144, 0.009, 0.009],
+ [0.133, 0.005, 0.005],
+ [0.003, 0.001, 0.001],
+ [0.019, 0.003, 0.002],
+ [0.265, 0.013, 0.013],
+ [0.231, 0.028, 0.029],
+ [0.132, 0.005, 0.005],
+ [0.137, 0.006, 0.006],
+ [0.142, 0.007, 0.007],
+ [0.395, 0.018, 0.018],
+ [0.182, 0.011, 0.011],
+ [0.128, 0.009, 0.01],
+ [0.453, 0.021, 0.02],
+ [0.078, 0.026, 0.002],
+ [2.304, 0.07, 0.07],
+ [0.076, 0.002, 0.001],
+ [3.189, 0.003, 0.003],
+ [3.966, 0.004, 0.004],
+ [7.141, 0.006, 0.006],
+ [0.76, 0.017, 0.023],
+ [0.069, 0.011, 0.002],
+ [0.066, 0.004, 0.004],
+ [0.075, 0.002, 0.002],
+ [0.731, 0.021, 0.021],
+ [3.198, 0.073, 0.07],
+ [0.005, 0.002, 0.002],
+ [0.313, 0.013, 0.013],
+ [2.821, 0.012, 0.011],
+ [2.615, 0.021, 0.021],
+ [3.17, 0.014, 0.014],
+ [3.17, 0.014, 0.014],
+ [0.111, 0.012, 0.012],
+ [0.06, 0.004, 0.003],
+ [0.017, 0.002, 0.002],
+ [0.061, 0.003, 0.003],
+ [0.116, 0.014, 0.013],
+ [0.02, 0.003, 0.003],
+ [0.02, 0.003, 0.003],
+ [0.018, 0.002, 0.002]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/results/20260922/c6a.large.json b/pgrust/results/20260922/c6a.large.json
new file mode 100644
index 0000000000..27b637caca
--- /dev/null
+++ b/pgrust/results/20260922/c6a.large.json
@@ -0,0 +1,60 @@
+{
+ "system": "pgrust",
+ "date": "2026-09-22",
+ "machine": "c6a.large",
+ "cluster_size": 1,
+ "proprietary": "no",
+ "hardware": "cpu",
+ "tuned": "no",
+ "tags": ["Rust","PostgreSQL compatible","column-oriented"],
+ "load_time": 12022,
+ "data_size": 9265914389,
+ "concurrent_qps": 0.535,
+ "concurrent_error_ratio": 0.71,
+ "result": [
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [0.002, 0.001, 0.001],
+ [1.35, 0.482, 0.482],
+ [1.812, 0.186, 0.186],
+ [0.002, 0.001, 0.001],
+ [0.194, 0.012, 0.012],
+ [2.043, 0.709, 0.738],
+ [7.652, 6.678, 5.462],
+ [1.24, 0.124, 0.127],
+ [1.489, 0.151, 0.153],
+ [2.214, 0.266, 0.266],
+ [3.434, 0.739, 0.706],
+ [2.598, 0.398, 0.4],
+ [1.377, 0.509, 0.507],
+ [10.147, 7.168, 7.196],
+ [0.082, 0.027, 0.003],
+ [31.617, 43.121, 18.425],
+ [0.678, 0.013, 0.013],
+ [13.457, 1.714, 0.188],
+ [18.9, 6.107, 0.129],
+ [37.219, 36.557, 0.305],
+ [1.555, 0.029, 0.03],
+ [0.271, 0.008, 0.003],
+ [0.798, 0.005, 0.005],
+ [0.169, 0.023, 0.004],
+ [3.116, 0.699, 0.696],
+ [31.506, 108.909, 107.917],
+ [0.005, 0.002, 0.002],
+ [2.526, 0.391, 0.391],
+ [4.92, 0.44, 0.453],
+ [7.121, 3.377, 3.456],
+ [32.663, 10.794, 5.313],
+ [42.38, 11.888, 1.048],
+ [1.176, 0.581, 0.58],
+ [0.208, 0.015, 0.015],
+ [0.054, 0.005, 0.006],
+ [0.2, 0.005, 0.005],
+ [0.376, 0.05, 0.049],
+ [0.063, 0.005, 0.005],
+ [0.052, 0.007, 0.007],
+ [0.043, 0.011, 0.011]
+]
+ }
+
\ No newline at end of file
diff --git a/pgrust/start b/pgrust/start
index 8251ccf250..06e236fe0b 100755
--- a/pgrust/start
+++ b/pgrust/start
@@ -1,24 +1,15 @@
#!/bin/bash
set -eu
. "$(dirname "$0")/env.sh"
-
-sudo install -d -o postgres -g postgres "$PGSOCK_DIR"
-
-# Runs as the `postgres` system user (the server refuses to run as root,
-# and the datadir is owned by postgres). RUST_MIN_STACK and the rlimit
-# raise thread/main stacks to match max_stack_depth=60000 — pgrust
-# requires both (deep recursive expression evaluation paths).
-sudo -u postgres \
- PGRUST_BIN="$PGRUST_BIN" PGDATA_DIR="$PGDATA_DIR" \
- PGSOCK_DIR="$PGSOCK_DIR" SERVER_LOG="$SERVER_LOG" \
- PGSHARE_DIR="$PGSHARE_DIR" TZDATA_DIR="$TZDATA_DIR" \
- EXTRA_SERVER_ENV="${EXTRA_SERVER_ENV:-}" \
- bash -c '
- ulimit -s 65520
- nohup env RUST_MIN_STACK=33554432 RUST_BACKTRACE=1 \
- PGRUST_TZDIR="$TZDATA_DIR" PGRUST_PGSHAREDIR="$PGSHARE_DIR" \
- $EXTRA_SERVER_ENV \
- "$PGRUST_BIN" -D "$PGDATA_DIR" -k "$PGSOCK_DIR" -p 5432 \
- -c listen_addresses="" \
- >> "$SERVER_LOG" 2>&1 &
- '
+$PSQL -tAc 'SELECT 1' >/dev/null 2>&1 && exit 0
+sudo install -d -o "$PGRUST_USER" -g "$PGRUST_USER" "$PGSOCKDIR"
+# The server runs as $PGRUST_USER (it refuses root; the datadir is owned by that user). The rlimit and
+# RUST_MIN_STACK match max_stack_depth=60000.
+$AS_PG env PGRUST_PREFIX="$PGRUST_PREFIX" PGDATA="$PGDATA" PGPORT="$PGPORT" PGRUST_HOME="$PGRUST_HOME" bash -c '
+ ulimit -s 65520 2>/dev/null || true
+ nohup env RUST_MIN_STACK=67108864 \
+ PGRUST_TZDIR=/usr/share/zoneinfo PGRUST_PGSHAREDIR="$PGRUST_PREFIX/share/postgresql" \
+ PGRUST_PARALLEL_COPY=1 PGRUST_PARQUET_PARALLEL=1 \
+ "$PGRUST_PREFIX/bin/postgres" -D "$PGDATA" -p "$PGPORT" >> "$PGRUST_HOME/server.log" 2>&1 < /dev/null &
+'
+exit 0
diff --git a/pgrust/stop b/pgrust/stop
index 943bc16e5c..fadad26dda 100755
--- a/pgrust/stop
+++ b/pgrust/stop
@@ -1,23 +1,6 @@
#!/bin/bash
. "$(dirname "$0")/env.sh"
-
-pid=$(sudo head -1 "$PGDATA_DIR/postmaster.pid" 2>/dev/null)
-[ -n "$pid" ] || exit 0
-
-# Fast shutdown, as the true-cold-run protocol requires.
-sudo kill -INT "$pid" 2>/dev/null || exit 0
-for i in $(seq 1 120); do
- sudo kill -0 "$pid" 2>/dev/null || exit 0
- sleep 0.5
-done
-
-# Still alive after 60s: immediate shutdown. The datadir is durable and the
-# next start recovers; better than leaving a half-stopped server pinning the
-# page cache through the "cold" cycle.
-echo "pgrust/stop: fast shutdown did not finish in 60s, escalating to SIGQUIT" >&2
-sudo kill -QUIT "$pid" 2>/dev/null || exit 0
-for i in $(seq 1 60); do
- sudo kill -0 "$pid" 2>/dev/null || exit 0
- sleep 0.5
-done
+PIDF="$PGDATA/postmaster.pid"
+[ -f "$PIDF" ] && kill -INT "$(head -1 "$PIDF")" 2>/dev/null
+for i in $(seq 1 120); do [ -f "$PIDF" ] && kill -0 "$(head -1 "$PIDF")" 2>/dev/null || exit 0; sleep 0.5; done
exit 0
diff --git a/pgrust/template.json b/pgrust/template.json
index 2fdd9c9dd9..b72bbde84f 100644
--- a/pgrust/template.json
+++ b/pgrust/template.json
@@ -1,11 +1,8 @@
{
"system": "pgrust",
+ "version": "v0.4-preview",
"proprietary": "no",
"hardware": "cpu",
"tuned": "no",
- "tags": [
- "Rust",
- "column-oriented",
- "PostgreSQL compatible"
- ]
+ "tags": ["Rust", "PostgreSQL compatible", "column-oriented"]
}