PostgreSQL 19 adds REPACK, a table rewrite that can remove dead-tuple storage and return unused space to the operating system. Its (CONCURRENTLY) mode keeps reads and writes available through most of the rewrite, but it still needs an ACCESS EXCLUSIVE lock for the final file swap. REPACK is a PostgreSQL 19 development/beta feature in the documentation cited here, not a feature to assume is available in every production installation.
First, distinguish reusable space from reclaimed disk space
PostgreSQL uses multiversion concurrency control (MVCC). An update or delete leaves an older row version behind until vacuuming can remove it. Plain VACUUM makes space from dead rows available for reuse inside the table, but usually does not shrink the table file or return that space to the operating system. There are exceptions, such as empty pages at the end of a table.
As an Amazon Associate I earn from qualifying purchases.
Autovacuum is intended to keep space use under control as rows change. Rewriting a table just to make it as small as possible is often counterproductive if the table will soon grow again. A rewrite is worth considering when substantial excess storage needs to be returned to the OS or when physical row order is an intentional goal.
What REPACK does—and what “online” means
REPACK copies live table contents into a new file, omitting dead tuples and retaining the free space allowed by the table’s fillfactor. The old and new files coexist until the operation completes, so the rewrite needs temporary disk capacity. PostgreSQL’s general rewrite guidance estimates extra space at approximately the size of the table.
#1 Best Overall
Without CONCURRENTLY, REPACK takes an ACCESS EXCLUSIVE lock for the rewrite, blocking reads and writes to the table. With (CONCURRENTLY), PostgreSQL copies the table while capturing changes made during the copy through logical decoding, then applies those changes before requesting the lock needed to swap files. Reads and writes can continue through most of the work, but the final swap still requires an ACCESS EXCLUSIVE lock. The manual also warns that concurrent REPACK is not MVCC-safe; “online” does not mean zero blocking or suitability for every workload.
Choose the operation based on the result you need
| Operation | Space result | Availability and use |
|---|---|---|
VACUUM or autovacuum |
Makes dead-tuple space reusable; usually does not return it to the OS. | Routine maintenance. Does not take the table-wide ACCESS EXCLUSIVE lock used by rewrite operations, though it generates I/O. |
VACUUM FULL |
Rewrites and compacts the table, returning space to the OS. | Requires temporary space and blocks table operations with an ACCESS EXCLUSIVE lock during processing. PostgreSQL 19 documentation marks it deprecated in favor of REPACK behavior; check documentation for the version you run. |
REPACK |
Rewrites the table to reclaim dead-tuple storage; USING INDEX can physically reorder rows. |
Use when reclaiming space or changing row order is important and a blocking rewrite is acceptable. |
REPACK (CONCURRENTLY) |
Rewrites for the same storage goal, with concurrent change capture. | Reads and writes continue through most of the operation; the final swap still needs an ACCESS EXCLUSIVE lock. Eligibility restrictions apply, and temporary space is required. |
pg_repack extension |
Can reorganize tables and indexes online. | A separate extension, not the core command. Its project documentation lists PostgreSQL compatibility through 19 and requires a primary key or qualifying unique index, plus substantial free disk. Verify compatibility and provider support for your deployed version. |
Check version status before planning a production run
The PostgreSQL 19 documentation page cited here identifies the version as unsupported and references PostgreSQL 19 Beta 4, released September 24, 2026. The release notes surfaced for this feature show a placeholder final-release date and an as-of date of September 14, 2026. Treat REPACK as a development/beta feature on that evidence, and check the current official release and documentation status before using it. Feature availability and exact behavior can change before a final release.
Rank #2
Preflight: confirm the table and server are eligible
- Privileges: the command requires the
MAINTAINprivilege on the table. - Indexes: REPACK refuses to run if the table has an invalid index. Remove or reindex the invalid index first.
- Temporary capacity: allow room for the new table copy while the old files remain. PostgreSQL’s general rewrite estimate is approximately the table’s size in extra disk space. Separately, the
pg_repackproject estimates about twice the combined size of target tables and indexes as free space for a full-table repack; that extension estimate is not a guaranteed capacity requirement for PostgreSQL’s core REPACK command. - Concurrent-mode eligibility: the documented exclusions include materialized views, unlogged tables, partitioned tables, system catalogs, TOAST tables, and tables using non-heap access methods. Concurrent mode also excludes tables without a primary key and index-based replica identity.
- Replication slots: concurrent mode requires that PostgreSQL can create another replication slot. Check the configured allowance, including
max_repack_replication_slots. - Transaction context: do not run
REPACK (CONCURRENTLY)inside a transaction block. - Operational impact: account for the rewrite’s I/O, temporary disk use, and the final lock. The command temporarily changes
search_pathtopg_catalog, pg_temp.
Run the documented command form
These examples show PostgreSQL 19 REPACK syntax; they are not a tested production procedure. Confirm the command exists in your installed version and check eligibility, privileges, disk headroom, index validity, and replication-slot configuration before running it.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches-- Rewrite a table to reclaim storage
REPACK employees;
-- Rewrite and reorder rows using an index
REPACK employees USING INDEX employees_ind;
-- Use concurrent mode and the previously selected clustering index
REPACK (CONCURRENTLY) employees USING INDEX;
The documented synopsis also supports VERBOSE and ANALYZE options, and a form that specifies columns. For the full syntax and option details, consult the PostgreSQL 19 REPACK command reference.
Rank #3
Use index-based reordering only for a specific access pattern
USING INDEX physically reorders table rows according to an index. PostgreSQL notes that this can help range queries or requests that return multiple rows with similar index values, but the benefit depends on how the application accesses the data. Reordering is not an automatic benefit of reclaiming space; use it when the intended access pattern justifies the rewrite.
Track progress and understand the operational trade-off
Core REPACK exposes progress through pg_stat_progress_repack. Use that view to observe the operation rather than assuming a completion time: the documentation cited here does not establish a universal duration or performance gain.
The trade-off is straightforward: ordinary vacuuming supports ongoing reuse without a full-table rewrite, while REPACK spends I/O and temporary capacity to build a compact replacement file. Concurrent mode reduces the period when table access is blocked, but adds change capture and eligibility constraints, and does not remove the final swap lock.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Quick Recap
Sources
- PostgreSQL 19: REPACK command reference
- PostgreSQL 19: Routine vacuuming
- PostgreSQL 19 release notes
- pg_repack project documentation
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




