pgrust README

The project's README from github.com/malisper/pgrust. As one markdown file: README.md.

pgrust

A Rust rewrite of Postgres that's faster than Postgres and ClickHouse.

Postgres 18.3 Regression suite: 100% Version: v0.2 License: AGPL-3.0

Try pgrust in your browser →   |   Discord   |   Updates   |   Issues

New: Video of Michael's talk at PlanetScale on pgrust — and the slides.

How AI Changes the Economics of JIT Compilers

pgrust is a re-implementation of Postgres meant to show what Postgres would look like if it was built in 2026. It is wire compatible and even SQL dialect compatible with Postgres. It passes all 46,066 tests in Postgres' regression suite. For the story of why we're building it, see pgrust: rebuilding Postgres in Rust with AI.

Every line is Rust, written to match the behavior of the C implementation. Rust makes it easy to re-architect several core Postgres pieces. pgrust has:

and many other really awesome pieces. The scheduler and the OOM killer go after two of the four horsemen behind thousands of Postgres outages. See What's new in v0.2 for more.

Status

pgrust is not production ready. Do not put data you care about in it.

pgrust currently passes the Postgres regression suite. It's faster than Postgres and ClickHouse, but it still has a lot of bugs. Our #1 priority right now is testing and reliability.

If you need production ready Postgres today, use Postgres.

Existing PostgreSQL extensions do not work. There is no stable extension ABI in pgrust yet. Some bundled contrib modules are ported, but PL/Python, PL/Perl, and PL/Tcl are not.

pgrust is specifically tuned for Graviton4 and the JIT compiler only targets Graviton4. pgrust will still work on other platforms, but will not have similar performance.

Performance

Measured on c8g.4xlarge (AWS Graviton4) against PostgreSQL 18.3.

On the ClickBench combined score, pgrust scored 18.5% faster than ClickHouse and hundreds of times faster than PostgreSQL. This was using pgrcolumnar, pgrust's builtin columnar layout.

On sysbench-oltp, pgrust achieved 30% higher throughput than Postgres 18.3 on read-only workloads at 300GB scale.

For a code-level walkthrough of one part of that speedup, read Rebuilding Postgres for 300x faster analytics: batching, operator fusion, and SIMD.

These runs were reviewed independently by Greg Smith, author of PostgreSQL 9.0 High Performance.

Two honest caveats. We had previously reported that pgrust was over 50% faster than Postgres. On Kubernetes we measure a larger OLTP gap, 50-60% rather than 30%, and we have not isolated why the same binaries behave differently there than on bare EC2, so we quote the lower number. Second, the binaries we publish are generic for their architecture. The benchmark numbers come from builds tuned for Graviton4 (-Ctarget-cpu=neoverse-v2), so you will not reproduce them exactly from a download.

Benchmarks and durability settings are unchanged from a default install: fsync is on. The harnesses are in benchmarks/ so you can run them yourself.

Writing

Testing

The most common question we get about pgrust is: how can anyone trust it? Just because we passed the test suite doesn't mean our code is correct. Getting to the point where people can trust pgrust is our number one priority today. (Getting the regression suite to pass at all took three failed attempts; we wrote up the dead ends in Postgres in Rust: getting the regression suite to pass.)

To achieve that goal, we're taking several different approaches:

  1. Of the 3000 user facing Postgres functions, we've been able to formally verify 1000 of them have identical behavior in pgrust with Kani. In the process of doing so we found 12 divergences between pgrust and Postgres. Four of those were bugs in Postgres itself. See proofs/.
  2. We're engaging with Antithesis to do simulation testing of pgrust to battle test pgrust.
  3. We're doing aggressive differential fuzz testing to ensure pgrust's behavior is identical to Postgres's.

Unsafe Code

pgrust uses unsafe code, but only for the specific things that need it. Postgres represents every internal value as a Datum, an untyped 8 byte value, and Rust has no safe equivalent, so the code that packs and unpacks internal values is unsafe. The same goes for the places where pgrust must match Postgres' memory layouts byte for byte.

If there are particular unsafes that are not necessary and removing them would not have an impact on performance, let us know, as we would love to remove more unsafes.

Quickstart

In your browser: https://pgrust.com, a full pgrust server compiled to WebAssembly, no install.

On your machine: pgrust does not ship its own initdb or psql yet, so each flow below installs the PostgreSQL 18 client tools first, then downloads pgrust, then initializes and starts a database. Paste the blocks top to bottom.

macOS (Apple Silicon)

# PostgreSQL 18 client tools (initdb, psql). The formula is keg-only, so
# Homebrew does not put it on your PATH; the export is required.
brew install postgresql@18
export PATH="$(brew --prefix postgresql@18)/bin:$PATH"

# Download pgrust and verify the checksum. Download with curl: curl does not
# set the quarantine flag a browser download gets, so Gatekeeper stays out of
# the way (see the note below).
curl -LO https://pgrust.com/downloads/v0.2/pgrust-0.2-macos-arm64
curl -LO https://pgrust.com/downloads/v0.2/pgrust-0.2-macos-arm64.sha256
shasum -a 256 -c pgrust-0.2-macos-arm64.sha256
chmod +x pgrust-0.2-macos-arm64

# Create a data directory using Postgres' initdb.
initdb -D /tmp/pgrust-data --no-locale --encoding UTF8 -U postgres

# pgrust reads the timezone database and other data files from a Postgres
# share directory at runtime. Without these two variables it looks in
# /usr/local/pgsql/share and refuses to start.
export PGRUST_PGSHAREDIR="$(brew --prefix postgresql@18)/share/postgresql"
export PGRUST_TZDIR="$PGRUST_PGSHAREDIR/timezone"

# Start the server. It runs in the foreground and logs to this terminal.
ulimit -s 65520
RUST_MIN_STACK=33554432 ./pgrust-0.2-macos-arm64 \
  -D /tmp/pgrust-data \
  -k /tmp -p 5432 \
  -c listen_addresses= \
  -c io_method=sync \
  -c max_stack_depth=60000

Leave the server running and connect from a second terminal:

export PATH="$(brew --prefix postgresql@18)/bin:$PATH"
psql -h /tmp -p 5432 -U postgres -c "select version()"

You should see pgrust 0.2 (PostgreSQL 18.3 compatible).

macOS Intel: the same flow works with pgrust-0.2-macos-x86_64 in place of pgrust-0.2-macos-arm64 (brew --prefix handles the different Homebrew prefix). There is also pgrust-0.2-macos-universal, a universal binary covering both.

A note on Gatekeeper: the binaries are not yet notarized by Apple. If you download with curl as above, the file is never quarantined and none of this comes up. If you download with a browser instead, macOS will refuse to run the binary with "Apple could not verify ... is free of malware". Clear the quarantine flag with xattr -d com.apple.quarantine pgrust-0.2-macos-arm64, or approve the binary under System Settings > Privacy & Security > "Open Anyway".

Linux (Debian and Ubuntu)

# Pick your architecture.
PLATFORM=linux-x86_64    # or: linux-aarch64

# PostgreSQL 18 client tools (initdb, psql) from the PGDG apt repo. On
# Debian and Ubuntu, initdb ships in the server package, postgresql-18, and
# is not placed on PATH, hence the export.
sudo apt-get update
sudo apt-get install -y curl ca-certificates gnupg
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
sudo apt-get install -y postgresql-18 postgresql-client-18
export PATH="/usr/lib/postgresql/18/bin:$PATH"

# Download pgrust and verify the checksum.
curl -LO "https://pgrust.com/downloads/v0.2/pgrust-0.2-$PLATFORM"
curl -LO "https://pgrust.com/downloads/v0.2/pgrust-0.2-$PLATFORM.sha256"
sha256sum -c "pgrust-0.2-$PLATFORM.sha256"
chmod +x "pgrust-0.2-$PLATFORM"

# Create a data directory using Postgres' initdb.
initdb -D /tmp/pgrust-data --no-locale --encoding UTF8 -U postgres

# pgrust reads the timezone database and other data files from a Postgres
# share directory at runtime. Without these two variables it looks in
# /usr/local/pgsql/share and refuses to start. Debian builds Postgres
# against the system tzdata, so PGRUST_TZDIR points at zoneinfo.
export PGRUST_PGSHAREDIR=/usr/share/postgresql/18
export PGRUST_TZDIR=/usr/share/zoneinfo

# Start the server. It runs in the foreground and logs to this terminal.
ulimit -s 65520
RUST_MIN_STACK=33554432 "./pgrust-0.2-$PLATFORM" \
  -D /tmp/pgrust-data \
  -k /tmp -p 5432 \
  -c listen_addresses= \
  -c io_method=sync \
  -c max_stack_depth=60000

Leave the server running and connect from a second terminal:

psql -h /tmp -p 5432 -U postgres -c "select version()"

You should see pgrust 0.2 (PostgreSQL 18.3 compatible).

Stopping, restarting, cleaning up

Building from source

You need the Rust toolchain (any rustup install works; rust-toolchain.toml pins the build to Rust 1.96.0 and rustup fetches it automatically) and the RE2 regex library:

cargo build --release --locked --bin postgres

The server binary lands at target/release/postgres. Run it exactly like the downloaded binaries in the quickstart, including PGRUST_PGSHAREDIR and PGRUST_TZDIR. Release builds refuse to compile without RE2 on purpose: a build with only the fallback regex engine is drastically slower on regex heavy workloads. The binaries we publish additionally use --profile dist, which turns on fat LTO; it produces a faster binary but takes much longer to compile.

Docker

The prebuilt image on Docker Hub is a drop-in replacement for the official postgres image: same env vars (POSTGRES_PASSWORD, POSTGRES_USER, POSTGRES_DB, PGDATA, ...), same /docker-entrypoint-initdb.d init scripts, same data volume at /var/lib/postgresql/data. Multi-arch (amd64 + arm64):

docker run -d --name pgrust -e POSTGRES_PASSWORD=secret -p 5432:5432 malisper/pgrust:v0.2

Then connect:

psql -h localhost -p 5432 -U postgres

To build the image from source instead, the repo's Dockerfile uses BuildKit cache mounts, so build it with buildx (the default on current Docker; on older installs run DOCKER_BUILDKIT=1 docker build instead):

docker buildx build --load -t pgrust .

What's new in v0.2

Executor

Parallelism

Storage

Other

Roadmap

v0.2 proves we can achieve better performance than Postgres and ClickHouse while maintaining identical behavior to Postgres. Next we're working on testing and battle testing pgrust and making it so people can trust pgrust with their data.

Beyond that we want to add:

Contributing

We are not actively accepting pull requests right now. If you want to help out with the project, reach out on Discord.

Please do still open an issue if something breaks, if setup is confusing, or if there is a Postgres behavior you want matched.

License

pgrust is licensed under AGPL-3.0. pgrust is an independent reimplementation of PostgreSQL; see NOTICE for attribution.

Contact

pgrust (malisper/pgrust)

Searching Database…

5.3K ·GitHub
What is this?pgrust is a from-scratch reimplementation of PostgreSQL in Rust, built to be wire- and SQL-dialect compatible with Postgres while being faster than both Postgres and ClickHouse.
Is this a drop-in replacement for my Postgres database, or something I'd have to migrate to?It is wire-compatible and SQL-dialect compatible with real Postgres and passes Postgres' own regression suite. The published Docker image is a direct drop-in replacement for the official postgres image, using the same env vars, init scripts, and data volume path.
How do I try pgrust?Download the Linux (Debian/Ubuntu) binary and run the server, then connect from a second terminal with psql; your data is preserved in the data directory across restarts. A prebuilt multi-arch Docker image is also available as a drop-in replacement for the official postgres image.
Is pgrust safe to use for real data?No - the project explicitly says it is not production ready and warns not to store data you care about in it. Existing PostgreSQL extensions also don't work yet since there is no stable extension ABI, and PL/Python, PL/Perl, and PL/Tcl are not ported.
Does pgrust need special ARM hardware to be fast?pgrust runs on other platforms, but its JIT compiler and performance tuning specifically target AWS Graviton4 ARM instances; on other CPUs it will work but won't match the published benchmark numbers.
How much faster is pgrust than Postgres and ClickHouse?On ClickBench it scored 18.5% faster than ClickHouse and hundreds of times faster than Postgres using its built-in pgrcolumnar columnar layout. On sysbench-oltp read-only workloads at 300GB scale it achieved 30% higher throughput than PostgreSQL 18.3.
How does the team know pgrust's behavior actually matches Postgres?They've formally verified identical behavior for 1,000 of ~3,000 user-facing Postgres functions using Kani (finding 12 divergences, 4 of which were bugs in real Postgres), plus differential fuzz testing and simulation testing with Antithesis.
What changed in the v0.2 release?A new vectorized, push-based executor with a copy-and-patch JIT, a thread-based concurrency model with a work-stealing query scheduler, the pgrcolumnar columnar storage format, and a built-in OOM killer that kills one worker instead of letting the OS kill the whole server.
Creator
malisper
Size
624.1 MB
Stars
5.3K
Age
5mo
Commits · 90 Days