If you've ever stared at a table that's still 138 MB after deleting 600,000 rows, you already understand the problem.
Postgres doesn't return bloated space to the OS after a VACUUM - it just marks dead tuples as reusable. The only built-in ways to actually reclaim space, VACUUM FULL and CLUSTER, require an ACCESS EXCLUSIVE lock for the entire operation. On a 1TB table in a production system, that's a non-starter.
So DBAs have reached for tools like pg_repack and pg_squeeze - third-party utilities that rewrite tables with minimal locking by leveraging logical decoding. They work, mostly. But they operate outside the core engine's safety guarantees, and that's enough to make conservative shops nervous.
Postgres 19 may change the calculus entirely.
The new REPACK command brings this functionality into the core engine, with a CONCURRENTLY option that holds an ACCESS EXCLUSIVE lock only during the brief final swap - not for the entire rewrite. Shaun Thomas walks through the full demo: 138 MB down to 52 MB, space genuinely returned to the OS.
There's also a USING INDEX option that replaces CLUSTER, reordering rows physically to match an index. In his benchmark, that dropped a query from 3,300 buffer reads to 49, and execution time from 3ms to 0.6ms.
Worth noting: REPACK CONCURRENTLY isn't MVCC-safe in a narrow edge case (transactions that have a snapshot open but haven't yet touched the table). Shaun explains when that matters and when it doesn't.
Postgres 19 is still in development, so this could still change. But if it ships, it'll be one of the more practically useful additions for anyone running large, write-heavy databases.
Read the full post:
hubs.la/Q04jqCKS0
#PostgreSQL #Postgres19 #DatabaseEngineering #DBA #OpenSource #Postgres #DatabasePerformance