Skip to main content

Postgres 19 Feature Preview: 64-bit MultiXactOffset

Tianzhou · Dec 17, 2025

Most Postgres operators know to watch transaction ID wraparound. Far fewer know there is a second, sneakier wraparound hiding right next to it: MultiXact member exhaustion. To be honest, until a cluster falls over from it, most teams have never heard of MultiXactOffset at all.

Here is the mechanism. PostgreSQL uses MultiXact structures to track row-level locks shared by multiple transactions. Each MultiXact holds members pointing to the transactions holding the lock. The catch is that MultiXactOffset, the pointer into that member storage, was a 32-bit value, capping total members at 2^32 (~4 billion) before wraparound. Transaction ID wraparound is well-documented and everyone monitors it. Member exhaustion sits in its shadow, and it catches most teams completely off guard.

This is not theoretical. In May 2025, Metronome experienced four separate outages when their PostgreSQL cluster exhausted MultiXact member space during a large data migration. The insidious part: their monitoring showed MultiXact ID usage under 50%, but PostgreSQL enforces a separate, poorly-documented member space limit. When it hit, every write failed with "This command would create a multixact" errors, and recovery meant hours of emergency vacuuming across a 30TB cluster. Four times. That is the kind of bug you only learn about the hard way.

Postgres 19 kills this limit outright with 64-bit MultiXact members, introduced by Maxim Orlov in commit bd8d9c9b, which widened the MultiXact member space to 64 bits.

What Changes

The 64-bit expansion has two practical effects.

No more wraparound emergencies. The 32-bit limit meant high-concurrency workloads could exhaust member space without warning. The worst offenders are tables with foreign keys, where many transactions share-lock the same rows. When n transactions share-lock a row, PostgreSQL creates O(n) MultiXacts with O(n²) members. That quadratic blowup is exactly how Metronome burned through 4 billion members faster than anyone expected. The 64-bit offset removes the ceiling entirely.

Simpler operations. PostgreSQL previously demanded aggressive anti-wraparound vacuuming specifically for member space. That is gone now. You still need regular vacuuming for disk space, but the "vacuum or die" panic for member exhaustion no longer exists.

The one tax: upgrading to Postgres 19 requires a pg_upgrade rewrite of the pg_multixact SLRU files. The good news is it happens automatically during the upgrade.

Closing Thoughts

The MultiXact member limit was the worst kind of operational risk. Poorly documented, invisible to standard monitoring, and catastrophic the moment you trip it. What I like about this fix is that Postgres 19 eliminates the limit instead of just bumping the threshold and buying a few more years. The 64-bit transaction ID story is still unresolved, but widening MultiXactOffset is a concrete down payment on retiring wraparound risk in PostgreSQL for good.

References

Back to blog

Explore the standard for database development