Parameter · Resource Usage / Memory
transaction_buffers
Sets the size of the dedicated buffer pool used for the transaction status cache. 0 means use a fraction of "shared_buffers".
- Default:
0 - Type: integer (8kB)
- Range: 0 … 1GB
- Applies: Restart required
In plain words
To decide if a row is visible, PostgreSQL often has to know whether the transaction that wrote it committed or aborted. That status (2 bits per transaction) is stored in pg_xact, the commit log. This is how many of its 8 kB pages are cached in shared memory.
For DBAs and operators
New in PostgreSQL 17 (before, the cache was a fixed 128 buffers at most). Default 0 = shared_buffers/512 clamped to 16–1024 buffers; must be a multiple of 16. One 8 kB page covers 32,768 transactions, so 1024 buffers cover ~33 million XIDs.
Lookups mostly hit recent pages; misses happen when queries read many rows written by old, not-yet-hinted transactions (first scan after a bulk load, rows touched long ago and never vacuumed, standbys). Hint bits set on the tuple after the first check avoid repeated lookups. Watch pg_stat_slru (name = 'transaction') and the XactSLRU / XactBuffer wait events. On large, busy systems that show those waits, 256–1024 is reasonable.
If pg_xact files are missing you get ERROR: could not access status of transaction 123456, which signals corruption or a manual deletion, not a sizing issue.
How to change it
Change in postgresql.conf or ALTER SYSTEM, then restart the server.
See it in context
SLRU caches Commit log, hint bits and subtransactions MVCC: row versions Snapshots and visibility