pgrust passed 100% of Postgres regression tests: SQLsmith segfaulted it in days
Contents
On July 9, 2026 (US time), the Hacker News front page carried “Postgres rewritten in Rust, now passing 100% of the Postgres regression tests” (807 points) and Zig creator Andrew Kelley’s “My Thoughts on the Bun Rust Rewrite” (783 points) at the same time. The day before, Bun’s official blog had published “Rewriting Bun in Rust” (777 points), which made three large-scale-AI-rewrite threads in 24 hours. pgrust’s 807 was the top score of the day.
As a follow-up to my May post on Bun’s one-million-line Rust port, this post goes through what pgrust actually is, and how the Bun side turned into a mud fight.
| Date (US time) | Thread | Points |
|---|---|---|
| Jul 8 | Rewriting Bun in Rust (Bun official blog) | 777 |
| Jul 9 | Postgres rewritten in Rust (pgrust repository) | 807 |
| Jul 9 | My Thoughts on the Bun Rust Rewrite (Andrew Kelley) | 783 |
graph TD
subgraph pg[pgrust]
A[Apr 20: pgrust published<br/>250k lines, 1/3 of regression tests] --> B[Apr 28: 67% passing]
B --> C[Jun 25: 100% of regression tests<br/>Show HN stalls at 6 points]
end
subgraph bz[Bun and Zig]
D[May 14: Bun Rust port<br/>1M lines merged to main] --> E[Late May: Zig formalizes<br/>ban on LLM contributions]
E --> F[Jul 8: Sumner publishes<br/>Rewriting Bun in Rust]
end
C --> G[Jul 9: collision on the HN front page<br/>pgrust 807pt / Kelley post 783pt]
F --> G
pgrust is a two-person side project
pgrust is a personal project by Michael Malis and Jason Seibel, not a company product. Malis is a former infrastructure engineer who ran a petabyte-scale Postgres cluster at Heap, and he has been writing about Postgres internals on his blog for years.
Work started in early April. The initial approach pointed Codex agents at the Postgres C source to explain subsystems and write minimal Rust equivalents, with Conductor (a git-worktree-based orchestrator) scaling that up to 17 parallel agents before his machine’s CPU maxed out. By the April 20 announcement it was 250,000 lines of Rust passing roughly a third of Postgres’s regression tests. In that post Malis wrote that he “was no longer reading most of the code.”
In June the approach changed. He dropped the from-scratch implementation, ran c2rust over the Postgres C source to get unsafe Rust (one crate per C compilation unit, roughly 1,000 crates), and then converted it crate by crate into safe Rust. The conversion runs on three Claude skills — pick the next crate, rewrite the crate, audit the rewrite. The old implementation was moved to an archive branch.
On June 25 he announced that pgrust passes 100% of PostgreSQL 18.3’s 46,000+ regression tests, passes the isolation tests, and can boot directly from an existing Postgres 18.3 data directory. His own Show HN stalled at 6 points; two weeks later a third-party resubmission climbed to 807.
The README and the blog state plainly that it is not production-ready, not performance-optimized, and not compatible with existing Postgres extensions. The license is AGPL-3.0, and that part is contested. AGPL extends the GPL’s source-disclosure obligation to network use: even without distributing a modified version, running it as a service for users triggers the obligation. Plain GPL only triggers on distribution. Databases usually run inside a SaaS rather than being distributed, so under AGPL the obligation reaches cloud providers too — the same lineage MinIO and MongoDB (before its SSPL move) used against cloud vendors. On HN the reaction included “Database & AGPL bad combination.”
What a 100% regression pass covers
pg_regress diffs query output text against expected files; 46,000 is the number of queries. The isolation tests, which check serialization of concurrent transactions, pass too. The recovery test suite (TAP-based, covering crash recovery), on the other hand, was at 34 of 47 passing at port time (issue #10, filed by Malis himself), and for external suites like sqllogictest or Jepsen his HN answer was “nothing major yet.”
The HN discussion centered on what that 100% means. Beyond the principle that passing a regression suite only proves those particular regressions are absent, commenters pointed out that running an LLM in a “this test fails, fix it” loop can produce code that special-cases its way through the tests — the Goodhart’s law concern that a test stops working as a metric once it becomes the target. On pgrust’s biggest change, the switch from process-per-connection to thread-per-connection, the existing tests were written against the process model and don’t exercise it. levkk, the author of PgDog, asked: “Just checking, is fsync on?” pg_regress can’t measure whether the I/O patterns are honest.
SQLite came up repeatedly as the comparison point. SQLite publishes a ratio of roughly 590 lines of test code per line of product code — a different order of testing investment than a single 100% regression number.
SQLsmith’s author produced a segfault within days
Andreas Seltenreich, author of the query fuzzer SQLsmith that has found many bugs in Postgres itself, started fuzzing pgrust on July 9 and filed a stream of issues.
One line — SELECT numrange_subdiff(1,1); — produced a segmentation fault (signal 11, issue #23). Postgres 18.3 returns 0 for that query, so the rewrite that leads with memory safety crashed on a query that C Postgres handles fine. There are also an internal error on a MERGE statement (#22), several errors where planner invariants break (#17, #21, #28), and a report that bytea literal validation is missing entirely (#13).
As a side effect, AI-written explanations sometimes leak out as runtime errors. In issue #20, a long note that reads like a development memo — “SubLink::clone: subselect is an embedded owned Query whose children are context-allocated; …” — came back as the ERROR message of a query.
The background here is that pg_regress was never built for 100% coverage. make check prioritizes finishing fast, and fuzzing runs like SQLsmith are part of Postgres’s development process, operated by humans. Converting a snapshot of the code gets you the snapshot; it doesn’t get you that process. HN’s evil-olive put it this way: converting one static snapshot into another static snapshot is meaningless — implement 14, then upgrade to 15, 16, 17, 18 with data preserved.
The published build measures slower, not faster
The README has an update about an unpublished newer version: 50% faster than Postgres on transaction workloads, roughly 300x faster on analytical queries (2x slower than ClickHouse on ClickBench). Third parties can’t verify those numbers. Someone did benchmark the published build: in issue #31, pgbench against vanilla Postgres 18.4 showed about 1/9 the TPS (728 vs 6,365) and initialization about 11x slower. There’s also a report of it getting OOM-killed under load (#30).
Malis himself acknowledges that a naive conversion doesn’t get faster — in the Bun thread he commented, “Even though the new Rust code mapped closely with the previous C code, it was 8x slower.” The 300x claim drew an HN response that such a number is impossible without breaking the synchronization that provides ACID guarantees — itself an unsupported guess, since a switch to columnar execution could legitimately produce numbers in that range. It can’t be judged until the code is published.
From people who read the code: one commenter counted 2,664 unsafe blocks and 1,835 unsafe functions, to which Malis answered that “most of the unsafes are confined to the parser which was generated by running c2rust over the Postgres parser” — the Postgres parser is itself generated from yacc/bison, so he deliberately kept that part as a mechanical port. Another reviewer pointed at error handling that mirrors the C return-value structure, ending up with a double check of a Result type plus a boolean.
The same morning, Zig’s creator went after Bun
The same morning the pgrust thread took off, Andrew Kelley published “My Thoughts on the Bun Rust Rewrite,” written as a response to the official blog post Jarred Sumner had published the day before.
Per Sumner’s post: the port took 11 days and 6,502 commits, running up to 64 parallel Claude agents in implementer/reviewer pairs, consuming 5.9 billion uncached input tokens and 690 million output tokens — about $165,000 at API pricing. The model was a pre-release Claude Fable 5, and the post estimates the work at roughly a year for three engineers. The verification target was Bun’s own test suite of about one million assertions. The Rust Bun has been the runtime inside Claude Code since v2.1.181, released June 17.
Kelley’s post runs technical criticism and personal attacks together, and reactions split down the middle. On Sumner as an employer, he relayed secondhand accounts that “Jarred was a stinky manager. Poor communication, unrealistic expectations, low empathy, no experience.” He continued that “Jarred was already writing slop well before he had access to LLMs,” and aimed at Anthropic: “It’s almost like the marketing department of a trillion dollar company has a lot of money riding on this article.” The post also disclosed that Sumner had been donating $60,000 a year to the Zig Software Foundation, and that the donation silently stopped after the acquisition.
On the technical side, Kelley went after the consistency of the test-suite argument. If the justification for shipping a million lines of unreviewed code is that the test suite catches everything, why does the post say the Zig code had so many annoying bugs? The suite that failed to catch bugs in the Zig code is, somehow, supposed to be sufficient for a million lines of unreviewed code. He also noted that LTO, used for the binary-size reduction, had been available in Zig all along, and that while the post reads as if the team had been fuzzing, on their calls he had been told they were not fuzzing anything.
And the post was edited after publication. The current conclusion carries a note: “I had unprocessed emotions of resentment, that were obvious to the reader, but not to myself. I’ve updated this conclusion section after self-reflection,” followed by “I hope you can give me some grace considering a trillion dollar company fired the first shot.” The first version called the fuzzing passage an “outright fabrication” — that wording now survives only in HN comment quotes, softened in the current text to “the post implies.”
On X, Dagster creator Nick Schrock wrote: “I have never actively wanted a programming language to fail but thanks to Andrew Kelley’s scurrilous, outrageous, classless post on @jarredsumner’s bun rewrite, I got there. Port every project from Zig to Rust.” The defense came too: “Andrew Kelley’s blog post was fine actually. God forbid someone holds opinions and has a personality that’s not filtered through 10 layers of corporate code of conduct censorship.” As of this writing (July 12), Sumner has not responded to Kelley directly. Kelley left Twitter and Reddit in 2023 and isn’t on X, so the exchange keeps running between each side’s supporters.
What’s left under the mud
Both cases share the same question: can a test suite stand in for a specification? In the May post I wrote that a machine-checkable goal — pass the same tests and benchmarks — makes the AI generate-and-verify loop tractable. Now we have a success case and a limit case at the same time. Bun ran its own million assertions, operated by the maintainer who wrote them. pgrust borrowed someone else’s test suite from the outside, and SQLsmith marked the edge of it within days.
There’s also the reading of this as a Zig-versus-Rust conflict. Zig formalized a policy in late May of not accepting LLM-generated contributions — in press coverage Kelley called LLM contributions “invariably garbage” — which left Bun unable to send AI-generated changes upstream to the Zig toolchain and maintaining a fork. Zig’s biggest production project moved to Rust under Anthropic, and the backlash to the criticism of that move boosted “port every project from Zig to Rust.” That’s the order in which it spread.
The license debate continues too, and its target is pgrust relicensing a mechanical conversion of permissively-licensed PostgreSQL code as AGPL-3.0. One camp argues a mechanical conversion is a derivative work that can’t shed the original license; another argues AI-generated code may not be copyrightable at all. Neither is settled. The contrast raised on HN was ncruces’s machine translation of SQLite to Go, which keeps the upstream copyright notices after conversion.
Compared with earlier rewrites
Turso (formerly Limbo) rewrote SQLite with deterministic simulation testing and fuzzing built in from day one, judging correctness by diffing against SQLite itself — a design forced by the fact that SQLite’s own test suite is proprietary, so there was no suite to borrow. The fish shell’s C++-to-Rust port was human-driven: multi-year, component by component, staying a working shell at every point along the way. Neither of this month’s two cases followed either procedure. The elapsed time: years for fish, 11 days for Bun, just under three months for pgrust.
The “don’t let AI do this” backlash also has history from before the rewrites. curl scrapped its bug bounty over the flood of AI slop reports this February, and the Linux kernel added an AI coding assistant policy to its source tree. The pgrust repository got its own version of the question as issue #24: “Is this a serious project or just AI slop?” One of the answers there: legitimacy gets measured by sustained maintenance, and Bun’s rewrite was done by Bun’s own maintainers — a different thing from an outsider’s drop.
The open questions are concrete. The 50%-faster and 300x-faster claims become checkable only when the code is published. Whether the isolation tests keep passing under thread-per-connection, and what happens to the remaining 13 recovery tests, are also waiting on publication. HN’s aeonfox proposed a quality metric for AI rewrites: differential fuzzing against Postgres itself, scored as the log10 of queries passed before the first divergence. That’s the common logarithm — surviving 100,000 queries scores 5, a million scores 6. That number can be measured against the published build starting today.
References
- pgrust (GitHub)
- pgrust: Rebuilding Postgres in Rust with AI (malisper.me)
- pgrust passes 100% of PostgreSQL’s regression tests (malisper.me)
- HN: Postgres rewritten in Rust, now passing 100% of the Postgres regression tests
- Rewriting Bun in Rust (Bun Blog)
- My Thoughts on the Bun Rust Rewrite (Andrew Kelley)
- HN: My Thoughts on the Bun Rust Rewrite
- pgrust issue #31: pgbench benchmark report
- Rewriting Bun in Rust (Simon Willison)