Postgres has to guess how to run a join query before it runs it, and the number of ways grows fast: the write-up counts 4,608 possible plans for a three-table query and roughly 8.9 quadrillion for a nine-table one. Picking well is famously hard — the standard paper asking “How good are query optimizers, really?” was written in 2015 and updated a decade later with the same answer.
Rohan Bansal’s observation is that checking a plan is much easier than finding one. You run it and time it. That asymmetry turns query planning into something a language model can be trained on with a single, unambiguous score: faster is better. He then trained a small open-weights model to emit explicit hints that override Postgres’s own choices, and measured the result.
How the experiment works
- Training data was the Cardinality Estimation Benchmark — about 13,600 generated queries on the standard IMDb dataset — with any query shaped like a validation query pruned out. Final scoring used a held-back set of 113 join-heavy queries from the Join Order Benchmark.
- The model went through supervised fine-tuning first, including learning from roughly 500 trajectories of a frontier agent at the same task, then agentic reinforcement learning: four proposed plans per query, each one actually executed against Postgres, with execution time as the reward and that reward flowing back into the weights.
- Timing noise was the main engineering problem. A candidate identical to the default plan, measured three times, could show a phantom 14–26% speedup about 20% of the time — so he used a custom scoring variant that treats anything within 5% of the default as zero and shrinks real gains, plus repeated interleaved measurements and clipping to keep one extreme plan from dominating.
- Compute was split across two machines: a rented 2x H100 node running the model and training, and four Postgres containers on his own desktop, joined over Tailscale. After finding that 92% of a rollout’s time was model inference, he switched to leasing a Postgres worker only during measurement, which allowed 20 concurrent rollouts instead of 4.
Results
- The starting model could only produce a valid plan for 71 of 113 queries, and was already 1.16x faster than Postgres where it could.
- After 1,200 reinforcement-learning updates: 101 of 113 valid plans, 1.41x geometric-mean speedup, 38 wins against 2 regressions.
- Taking the best of up to 15 candidates per query pushed it to a 1.81x geometric-mean speedup with 68 wins and no regressions, and a 44.7% reduction in total query latency.
- What the model learned is legible: mostly rewriting join order, forcing parallel execution, and fixing a single scan. It developed preferences — nested loops over hash joins, index scans over bitmap and sequential — and liked switching off sorts and setting
random_page_costto 1.1.
Why the small model is the point
The headline number is the least interesting part. The argument is about the recipe: a company with its own data, a niche domain, and a measurable objective can build a small RL environment, spend a modest sum, and get a 4B model that beats a general-purpose planner at one specific task. The total bill here was $1,200 — about $800 for 95 hours of the rented GPU node, $400 in API fees for the frontier demonstration trajectories, plus electricity.
He is careful not to overclaim in the other direction. The distillation step is itself evidence that frontier models are not going anywhere, and the write-up is framed as a proof of a pattern rather than a product.
What the thread adds
The 43-comment thread on Hacker News is mostly people who know query planners reading the setup closely — and then asking what the benchmark does and does not hold constant.
- refibrillator — the exact conditions behind the 1.81x, spelled out: an 8 GB dataset that fits entirely in memory,
shared_buffersset to a fraction of that, queries warmed before timing, read-only SELECTs. The warning attached is about overfitting to the workload and about whether the plans hold up at scale — with credit to the author for writing the experiment up at all. - Someone — the cost accounting the write-up does at the end but never puts beside the results: the ~95 hours of rented GPU time, and then the practical question of whether you can afford periodic retraining to keep plan quality up. dvt answers that it is comparable to a scheduled backup window, and argues that deterministic techniques — using actual column distributions instead of assuming uniform ones — would likely beat retraining. Their comparison is compilers: software “carefully crafted for decades.”
- fsmv — a correctness worry rather than a speed one: how do you know a hinted plan actually does what the query asked? amluto answers that hint systems are built so that any accepted hint must still be a valid plan for that query; polyphilz, the author, adds that
pg_hint_planemits a debug log confirming whether the hint was used, which he relied on during evaluation. - jwpapi — questions the headline number on the grounds that training and testing ran on the same data. The write-up does split by query template — trained on the estimation benchmark with join-order-benchmark shapes pruned, validated on the 113 join-order queries — so the narrower version of the worry is that both benchmarks run against the same IMDb tables, and that the best-of-15 selection uses each query’s own measured timings to pick the winner.
- kingjimmy and tintor — “Aren’t optimizations supposed to be deterministic?” tintor’s answer: no, because plan choice depends on summary statistics that can be stale. cowboylowrez offers a theory rather than a finding — that a network trained in a closed world, like the chess engines the author cites elsewhere, could apply plan rewrites the way hand-written heuristics do.
- hamilyon2 — the blunt-weapon objection: the solution space is math-heavy and workload-specific, so reach for an AlphaGo-style learned heuristic rather than a language model. yipinwong proposes the hybrid: keep both, use whichever produces the better plan.
- devsda — on the write-up’s closing line that distillation from frontier trajectories proves large models are not going anywhere: that admission invites distillation accusations between closed and open model makers. pyaamb adds that it is worth knowing what open-weights work would lose if frontier labs convince the courts that distillation is illegitimate.
The question the write-up does not answer
Three commenters press the same gap in different words: refibrillator, jwpapi and Someone all ask whether a 1.81x measured on an in-memory, warmed, read-only benchmark transfers to a real workload. The write-up describes the join-order benchmark as a test of cardinality estimation and join ordering, and makes no claim about transactional or cold-cache workloads — which leaves the translation to production as the reader’s problem, and that is where the thread spends most of its energy.
A note on reading comments as evidence: HN handles are pseudonymous and the site publishes no per-comment scores, so the ordering here is HN’s own ranking, not a vote. This is a slice of a 43-comment thread.