When maintenance loses the race: the vacuum PostgreSQL will not let you skip
How production PostgreSQL operators keep the 32-bit transaction-ID counter from running out: the anti-wraparound vacuum that freezes old rows, what pins or stalls it, why it will not yield to lock waiters, and how operators measure and schedule it, reconstructed from the engine's source and commits, GitLab's public incident tracker and runbooks, and tool maintainers' issue threads.
PostgreSQL stays writable only while a throttled background job freezes old rows faster than write traffic spends a 2^31 transaction budget. This guide reconstructs how that race is run and lost from the engine's own code and commit history, five years of GitLab incidents and runbooks, and the pg_repack, pganalyze and Joyent records. A reader leaves able to size freezing as throughput against a deadline, keep the xmin horizon clear, gate deploys and repacks on freeze age, and recover at the limit without the single-user mode most runbooks still prescribe.
The recurring failure is not the database running out of IDs but the safety vacuum arriving: proc.c cancels a blocking autovacuum only if it is not working to prevent wraparound, so the one vacuum you cannot hurry is the one that never steps aside, and GitLab, pg_repack users on RDS and (per the postmortem index) Joyent all met it at the lock queue rather than at the cliff.
What you get out of it
- The anti-wraparound vacuum is the only autovacuum the lock manager will not cancel; in March 2025 the engine began moving freezing into insert-triggered vacuums for that stated reason, and GitLab now gates repacks on freeze age because it 'cannot be deferred or skipped'.
- Freezing is a capacity, not a chore: GitLab.com spent the 200M forced-vacuum budget in under three days (more than 67M XIDs a day, about a month of total runway), and its runbooks measure daily vacuum time per worker against time to the horizon with a hard SLO at one third.
- The number is easy to collect and hard to read: GitLab's wraparound metric existed unwatched, with the multixact age computed by the wrong function, until a May 2021 near miss whose on-call estimate of 12 hours to shutdown was really 27 days.
- A vacuum that runs is not a vacuum that freezes: a corrupt index made every vacuum of one customer's ci_builds abort before freezing until the database went read-only, and a 2019 engine optimisation that skipped wraparound jobs locked autovacuum into retrying them and was reverted.
- Operator runbooks lag the engine by years: upstream called single-user recovery 'terrible advice' in October 2023 (master only, no back-patch), yet GitLab's alert runbook, edited July 2026, still predicts shutdown and single-user recovery.
Scope
Why this, now. Between March and October 2026 PostgreSQL raised its wraparound warning margin to 100M, added wraparound-first autovacuum prioritisation, widened its OID counter to 8 bytes and reworded its warnings, while on 5 August 2026 an anti-wraparound vacuum blocked GitLab.com's deploys for five hours.
What it does not cover. Table and index bloat as a performance topic, sequence and primary-key exhaustion, managed-service internals, and the content of the Sentry, Joyent and Mandrill postmortems and of the PostgreSQL mailing lists and commitfest, which were unreachable from this session.
Other field guides
The data survives the upgrade. The database around it does not.
Reconstructs major-version database upgrades from GitLab's public change and incident tracker, Zalando's Spilo automation, Supabase's platform docs a…
22 sources · 8 organisations · 5 postmortemsCorrectness, then cost, then neighbours: ten years of TiDB, read from its own design record
PingCAP has published a dated design document or RFC for nearly every substantial change to TiDB and TiKV since 2018, plus a release note for every v…
26 sources · 5 organisations · 4 postmortemsThe shim outlives the migration: ten years of Sentry, read from its own deletions
Every team that outgrows its first database plans the new one; almost nobody plans the period when both are running. This guide measures that period …
31 sources · 3 organisations · 6 postmortems