DB Internals AtlasPostgreSQL 18.6 Home About

Parameter · Vacuuming / Freezing

vacuum_freeze_min_age

Minimum age at which VACUUM should freeze a table row.

  • Default: 50000000
  • Type: integer
  • Range: 0 … 1000000000
  • Applies: Session (any user)

In plain words

Freezing marks a row as "visible to everyone, forever", so its transaction ID no longer matters. VACUUM only freezes rows older than this age (50 million transactions), on the theory that younger rows may still be updated soon and freezing them would be wasted work.

For DBAs and operators

When VACUUM processes a page, tuples whose xmin is older than OldestXmin − vacuum_freeze_min_age are frozen. Since PostgreSQL 16, VACUUM also freezes a whole page opportunistically when it is writing a full-page image of that page to WAL anyway and freezing makes it all-frozen (and since 18, normal vacuums eagerly scan some all-visible pages too, see vacuum_max_eager_freeze_failure_rate).

After an aggressive vacuum the table's age drops to roughly this value. The effective value is capped at half of autovacuum_freeze_max_age.

  • Lower (e.g. 0–5M) for tables loaded once and rarely changed: rows freeze on the first pass, so later anti-wraparound vacuums find little to do. VACUUM (FREEZE) is the same as setting it to 0 for one run.
  • Higher wastes less effort on rows that churn, but leaves more to freeze later.

VACUUM VERBOSE / autovacuum logs show frozen: N pages from table (x% of total) had M tuples frozen.

How to change it

Any user can change it for their session with SET.

See it in context

XID wraparound and freezing VACUUM Free space map and visibility map MVCC: row versions

Related parameters

vacuum_freeze_table_age autovacuum_freeze_max_age vacuum_multixact_freeze_min_age

All Vacuuming parameters