Changelog
Change is the only constant. All the works here gets corrected, updated and/or extended after publication. PostgreSQL releases are major factor, readers catch things I got wrong or misleading. This page is a honest record of that. Every publication and every revision, newest first.
2026
- new How TABLESAMPLE picks rows TABLESAMPLE picks addresses, not rows: SYSTEM samples come in bundles, BERNOULLI with REPEATABLE drifts after an UPDATE, and a hashed key gives you the same rows tomorrow.
- new Postgres relation files, filed under base/ The files behind a PostgreSQL table: relfilenode versus OID, the fsm, vm, and init forks, 1GB segments, and what od on the file shows that pageinspect on the buffer doesn't.
- updated PostgreSQL Storage Internals New chapter 3, Postgres relation files, filed under base/: where a page lives on disk, the forks that share its relfilenode, and why the file and the buffer disagree until a checkpoint.
-
updated
Instant database clones with PostgreSQL 18
Corrected the description of the default
template1database, theWAL_LOGstrategy, and which files a single UPDATE touches.
- new What REPACK (CONCURRENTLY) costs while it runs PostgreSQL 19 comes with online table rewrites. Measured against pg_repack and pg_squeeze REPACK (CONCURRENTLY) is the fastest and the lightest on WAL under writes. Here's what it does to vacuum, readers, writers and old snapshots while it runs, and what to check before you start it.
-
updated
The Bloat Busters: pg_repack vs pg_squeeze
Links to What REPACK (CONCURRENTLY) costs while it runs, which measures core
REPACK (CONCURRENTLY)against both extensions on PostgreSQL 19.
-
updated
The Bloat Busters: pg_repack vs pg_squeeze
PostgreSQL 19 adds
REPACK (CONCURRENTLY)to core. Updated the comparison with measured WAL volume, swap stalls, repeatable-read visibility, and concurrent memory limits for both extensions, plus pg_squeeze's 18.6+output_plugin_librariesrequirement.
- new Where PostgreSQL stores row locks What SELECT FOR UPDATE, FOR SHARE, and a foreign key check actually write into the tuple header. t_xmax as a locker, the infomask bits that say so, MultiXactIds when two sessions lock the same row, and the pg_multixact files that grow behind them.
-
updated
Read your own writes, off the primary
Inside a transaction block,
WAIT FORhas to come first. Sincef7c0929170ait fails if the session already holds a lock, even withNO_THROW. REPEATABLE READ works too, as long as the wait runs before the first query. thanks to Sami Imseih
-
updated
Introduction to Buffers in PostgreSQL
Reworked the article around a live
pg_buffercachesession: what the buffer pool actually holds after a query, why aSELECTcan dirty a page, and how eviction plays out. Also corrected the version that introducedvacuum_buffer_usage_limit.
- new The unbearable lightness of one more index Thirty PostgreSQL schemas written by coding agents, loaded and measured. The indexes are competent; the cumulative cost is not.
-
updated
Read your own writes, off the primary
One naming cleanup landed after this was written. The command tag the statement returns is
WAIT, while the beta documentation called itWAIT FOReverywhere, and the tag cannot change once 19.0 ships. The -hackers agreement is to keep the tag and rename the documentation, error messages, and reference page toWAITinstead. The syntax does not change, you still writeWAIT FOR LSN '...', but if you match on error text or link to the docs page, the wording and the anchor will differ from the betas.
- new Read your own writes, off the primary WAIT FOR in PostgreSQL 19 lets a reader block until the replica has replayed a specific LSN. Measured against sticky routing, sleeps, and synchronous commit, on a replica that misses the write 99% of the time.