Assess multixact wraparound risk
Multixact IDs have their own counter, their own freeze thresholds and their own way of shutting a cluster down, and almost nobody monitors them. The lab shows the real empty xmax shape after setup; the monitoring query is the point.
Problem
What you're actually looking at
The symptom as it shows up on a real server.
When more than one transaction locks the same row at the same time, PostgreSQL cannot store a single xmax, so it allocates a MultiXactId that names the set of lockers. Those IDs come from a 32-bit counter that wraps, exactly like transaction IDs, and they have a separate freeze threshold that autovacuum enforces separately. A workload built on SELECT ... FOR SHARE or foreign keys over hot parent rows can consume them far faster than it consumes XIDs, and the usual age(relfrozenxid) dashboard shows nothing at all.
consignment_holds is read with SELECT ... FOR SHARE by several settlement workers whose transactions overlap. The rows involved are the same handful of holds, over and over.
Simple terms
When two or more transactions lock the same row at once, PostgreSQL cannot record just one locker, so it creates a MultiXactId that names the whole set. Those IDs come from their own 32-bit counter that wraps around just like transaction IDs, with its own separate freeze deadline, and almost nobody watches it. A workload full of SELECT ... FOR SHARE, or foreign keys over the same hot parent rows, can burn through them fast while the usual transaction-age dashboard shows nothing wrong. The point of this one is the query that surfaces the risk before it bites.
Full runbook for this incident
- The full identify checklist, the exact signals that tell you it's this incident
- Every diagnostic query; lab output is attached only to the steps we actually captured
- The resolution path and the pitfalls that make it worse
- Mitigation steps to stop it recurring, plus a verify-you're-done query
Card required. Cancel before day 7 and you are not charged.
More in this category
Other Vacuum & bloat runbooks
Neighbouring incidents that share the same diagnostic surface.
Connected
How this connects to the rest of the library
A live view of this page's real cross-references, what explains it, what fixes it, what to tune, and where to go next. Every link is an authored relationship, not a guess.
Fixes these errors
Need the full procedure?
Pro runbooks finish the incident path
Free runbooks teach the shape. Pro opens the full step transcript, edge cases, and prevention depth.