/arcana

Arcana

Everything vacuum-adjacent that is worth knowing, in the order it tends to hurt you. Every term in the report links here; every entry here links back to a place in the product where you can watch it happen.

xminThe xid that created a row version. Half of every visibility check.system column · page + demoxmaxThe xid that deleted or superseded a row version. Set, never cleared, until vacuum.system column · page + demodead tupleA row version no live snapshot can reach. Occupies a page until vacuum frees the line pointer.concept · page + demoxmin horizonThe oldest snapshot anyone still holds. Vacuum may not touch anything newer, no matter how you tune it.concept · page + demoHOT updateAn update that stays on the same page and touches no indexed column: no index writes at all.concept · page + demofillfactorHow full inserts pack a page. Below 100, the reserve is what makes HOT updates possible.setting · page + demobloatPages kept only because dead tuples were never reclaimed. The file does not shrink without a rewrite.concept · page + demovisibility mapTwo bits per page: all-visible, all-frozen. What lets a normal vacuum skip most of a big table.structure · pageautovacuum_vacuum_scale_factorFraction of n_live_tup added to the trigger threshold. The single most misconfigured value on large tables.setting · page + demoautovacuum_vacuum_thresholdThe fixed part of the trigger. With scale factor 0, it alone decides the vacuum cadence.setting · page + demoautovacuum_vacuum_insert_scale_factorThe insert-side scale factor (Postgres 13+). What gets append-only tables vacuumed at all.setting · pageautovacuum_vacuum_insert_thresholdInserted rows before an insert-triggered vacuum. Freezes append-only pages while they are still in cache.setting · pageautovacuum_analyze_scale_factorWhen the planner's statistics refresh. Stale statistics break plans, partition pruning included.setting · pageautovacuum_analyze_thresholdThe fixed part of the analyze trigger, same shape as the vacuum threshold.setting · pageautovacuum_naptimeHow often the launcher visits each database. The floor on any vacuum cadence you can configure.setting · pageautovacuum_max_workersWorkers across the whole cluster, default 3. Big tables occupy them for hours and starve the rest.setting · pageautovacuum_vacuum_cost_delayMilliseconds the worker sleeps per cost_limit units. Pre-12 clusters still carry 20 ms.setting · page + demoautovacuum_vacuum_cost_limitCost units the worker may spend before it sleeps. The budget all workers share.setting · page + demovacuum_cost_page_hitPrice of a page found in shared_buffers: 1 unit. The cheap end of the cost model.setting · page + demovacuum_cost_page_missPrice of reading a page from disk. 2 since Postgres 14; the old 10 priced spinning rust.setting · page + demovacuum_cost_page_dirtyPrice of dirtying a page: 20 units, the dominant term. Writes are what the throttle really meters.setting · page + demomaintenance_work_memMemory for the dead-TID store. Too small meant multiple index passes, until Postgres 17.setting · pagefreezeMarking a row version permanently visible so its xmin can be forgotten.concept · page + demorelfrozenxidThe oldest unfrozen xid a table can contain. Its age is the number wraparound monitoring watches.system column · page + demovacuum_freeze_min_ageHow old a row must be before a vacuum freezes it. Must be shorter, in time, than the vacuum interval.setting · pagevacuum_freeze_table_ageTable age that escalates the next vacuum to aggressive, on your schedule instead of the forced one.setting · pageaggressive vacuumA pass that ignores the visibility map and cannot be skipped. Triggered by table age, not by dead rows.concept · page + demoautovacuum_freeze_max_ageTable age at which a freeze pass stops being optional, even with autovacuum off.setting · page + demowraparound32-bit xids run out. At 3M remaining the cluster refuses writes until a vacuum catches up.failure mode · page + demovacuum_failsafe_ageThe emergency brake (Postgres 14+): at this age vacuum drops throttling and index cleanup to freeze faster.setting · pagemultixactShared row locks stored out of line. Has its own age, its own freeze limit, its own way to fill a disk.structure · pageautovacuum_multixact_freeze_max_ageThe multixact counterpart of freeze_max_age. Member space can run out long before this age looks bad.setting · pageTOASTSide storage for oversized values. A separate table with its own autovacuum settings, tuned via the toast. prefix.structure · pagetable rewriteThe one operation that gives pages back to the disk. Four tools do it, and the lock is what separates them.operation · page
Definitions follow PostgreSQL 16 behaviour and note where newer or older versions differ. Every term in the report links here, and every entry links to a page, the tagged ones with a demo you can drag.
Arcana — everything vacuum-adjacent worth knowing