DB Internals AtlasPostgreSQL 18.6 Home About

Parameter · Resource Usage / Memory

subtransaction_buffers

Sets the size of the dedicated buffer pool used for the subtransaction cache. 0 means use a fraction of "shared_buffers".

  • Default: 0
  • Type: integer (8kB)
  • Range: 0 … 1GB
  • Applies: Restart required

In plain words

Savepoints and PL/pgSQL EXCEPTION blocks create subtransactions. PostgreSQL records each one's parent in pg_subtrans. When a session has more than 64 open subtransactions, other sessions have to look parents up there a lot; this cache keeps those pages in memory.

For DBAs and operators

New in PostgreSQL 17. Default 0 = shared_buffers/512, between 16 and 1024 buffers; multiple of 16. The classic problem it softens is subtransaction overflow: each backend can advertise only 64 subxact IDs in shared memory; beyond that its entry is marked overflowed, snapshots become overflowed, and visibility checks by every session may need pg_subtrans lookups. Symptoms: many sessions waiting on SubtransSLRU / SubtransBuffer, often on hot standbys, CPU spikes, throughput collapse while one long transaction uses many savepoints.

-- PG16+: subtransactions per backend
SELECT pg_stat_get_backend_pid(b) AS pid,
       s.subxact_count, s.subxact_overflowed
  FROM pg_stat_get_backend_idset() AS b,
       pg_stat_get_backend_subxact(b) AS s;

The simpler check is pg_stat_slru (name = 'subtransaction', rising blks_read) plus wait events. Bigger buffers help, but the real fix is fewer savepoints per transaction (ORMs that wrap every statement in a savepoint, exception blocks in loops).

How to change it

Change in postgresql.conf or ALTER SYSTEM, then restart the server.

See it in context

SLRU caches Snapshots and visibility Hot standby and recovery conflicts Commit log, hint bits and subtransactions

Related parameters

transaction_buffers shared_buffers

All Resource Usage parameters