How to Understand Buffer Setting Parameters in PostgreSQL from postgresql.conf

When most people talk about PostgreSQL memory tuning, they usually mention only three settings: shared_buffers, wal_buffers, and temp_buffers. In Postgresql, there are some important parameters related to the buffer settings and they play bigger roles in postgres than these parameters named shared_buffers,wal_buffers etc.

While exploring PostgreSQL configuration files during research, we checked the buffer-related parameters inside postgresql.conf and found several specialized buffer settings that many users never notice. These settings reveal how PostgreSQL manages not only table data, but also transaction metadata, notifications, concurrency control, and internal caches.

Discovering Buffer Settings in PostgreSQL

First of all, we need to check the path of the postgres configuration file like this.

show config_file ;

Result :

               config_file               
-----------------------------------------
 /etc/postgresql/18/main/postgresql.conf
(1 row)

The first step was searching for all buffer-related settings inside the PostgreSQL configuration file.

cat /etc/postgresql/18/main/postgresql.conf | grep buffers

Result :

shared_buffers = 128MB            # min 128kB
#temp_buffers = 8MB              # min 800kB
# SLRU buffers (change requires restart)
#commit_timestamp_buffers = 0    # memory for pg_commit_ts (0 = auto)
#multixact_offset_buffers = 16   # memory for pg_multixact/offsets
#multixact_member_buffers = 32   # memory for pg_multixact/members
#notify_buffers = 16             # memory for pg_notify
#serializable_buffers = 32       # memory for pg_serial
#subtransaction_buffers = 0      # memory for pg_subtrans (0 = auto)
#transaction_buffers = 0         # memory for pg_xact (0 = auto)
#wal_buffers = -1               # min 32kB, -1 sets based on shared_buffers

At first glance, this list shows that PostgreSQL uses multiple dedicated buffer pools for different subsystems.

Why PostgreSQL Uses Different Buffers

PostgreSQL does not rely on a single memory cache for everything. Instead, it separates memory responsibilities.

Some buffers cache user data pages.

Some buffers handle WAL records.

Some buffers store transaction status.

Others support row locking, notifications, or serializable transactions.

This design helps PostgreSQL scale efficiently under concurrent workloads.

1.shared_buffers

This is the primary shared memory cache for table pages and index pages.

Whenever PostgreSQL reads data from disk, it tries to keep frequently used blocks in shared_buffers so future reads are faster.

pg_settings Output

Query :

select * from pg_settings where name = 'shared_buffers';

Result :

name            | shared_buffers
setting         | 16384
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the number of shared memory buffers used by the server.
extra_desc      | 
context         | postmaster
vartype         | integer
source          | configuration file
min_val         | 16
max_val         | 1073741823
enumvals        | 
boot_val        | 16384
reset_val       | 16384
sourcefile      | /etc/postgresql/18/main/postgresql.conf
sourceline      | 131
pending_restart | f

The value is 16384 pages, and each page is 8kB.

So:

16384 × 8kB = 128MB

That matches the value from postgresql.conf.

This is the most important general-purpose PostgreSQL cache.

2. temp_buffers

This setting controls the memory used for temporary tables created by a session.

These buffers are private to the session and are not shared globally.

pg_settings Output

Query :

select * from pg_settings where name = 'temp_buffers';

Result :

name            | temp_buffers
setting         | 1024
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the maximum number of temporary buffers used by each session.
extra_desc      | 
context         | user
vartype         | integer
source          | default
min_val         | 100
max_val         | 1073741823
enumvals        | 
boot_val        | 1024
reset_val       | 1024
sourcefile      | 
sourceline      | 
pending_restart | f

1024 × 8kB = 8MB

Purpose

Used when working with temporary tables such as:

CREATE TEMP TABLE ...

Each session can allocate its own temporary buffers.

3. wal_buffers

In postgresql, the data is actually written to a file before flushing to disk and the name of the file is WAL ( write ahead log ).The contents of the wal files are actually stored in wal buffers before flushing to the wal files.

WAL stands for Write-Ahead Logging, one of PostgreSQL’s most important durability mechanisms.

pg_settings Output

Query :

select * from pg_settings where name = 'wal_buffers';

Result :

name            | wal_buffers
setting         | 512
unit            | 8kB
category        | Write-Ahead Log / Settings
short_desc      | Sets the number of disk-page buffers in shared memory for WAL.
extra_desc      | -1 means use a fraction of "shared_buffers".
context         | postmaster
vartype         | integer
source          | default
min_val         | -1
max_val         | 262143
enumvals        | 
boot_val        | -1
reset_val       | 512
sourcefile      | 
sourceline      | 
pending_restart | f

512 × 8kB = 4MB

Purpose

When INSERT, UPDATE, or DELETE operations happen, WAL records are first placed in memory here before being flushed to disk.

What Are the Other Buffers?

The remaining settings are mostly specialized internal caches, many connected to PostgreSQL’s SLRU system.

SLRU means Simple Least Recently Used. It is a lightweight caching mechanism used for internal metadata pages.

These are not data-page caches like shared_buffers.

4. commit_timestamp_buffers

This parameter is mainly used to store the commit times related to the transaction.

This supports storing and reading commit times of transactions when commit timestamp tracking is enabled.

pg_settings Output

Query :

select * from pg_settings where name = 'commit_timestamp_buffers';

Result :

name            | commit_timestamp_buffers
setting         | 32
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the size of the dedicated buffer pool used for the commit timestamp cache.
extra_desc      | 0 means use a fraction of "shared_buffers".
context         | postmaster
vartype         | integer
source          | default
min_val         | 0
max_val         | 131072
enumvals        | 
boot_val        | 0
reset_val       | 32
sourcefile      | 
sourceline      | 
pending_restart | f

32 × 8kB = 256kB

Purpose

Useful when PostgreSQL needs to know when a transaction is committed.

5. multixact_offset_buffers

This parameter is mainly used to store the multiple transaction id’s of postgresql.In PostgreSQL, MultiXact means a special locking mechanism used when more than one transaction needs to lock the same row at the same time.

It is short for Multiple Transaction ID.

Instead of storing just one transaction ID (XID) in a row’s lock field, PostgreSQL creates a MultiXactId that represents a group of transaction IDs.

MultiXact is used when multiple transactions hold row locks on the same tuple.

pg_settings Output

Query :

select * from pg_settings where name = 'multixact_offset_buffers';

Result :

name            | multixact_offset_buffers
setting         | 16
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the size of the dedicated buffer pool used for the MultiXact offset cache.
extra_desc      | 
context         | postmaster
vartype         | integer
source          | default
min_val         | 16
max_val         | 131072
enumvals        | 
boot_val        | 16
reset_val       | 16
sourcefile      | 
sourceline      | 
pending_restart | f

16 × 8kB = 128kB

Purpose

Tracks where a MultiXact entry starts.

6. multixact_member_buffers

Used for storing MultiXact members.MultiXact members are the individual transactions inside a MultiXact group.

If a MultiXact is a container, the members are the transaction IDs stored inside that container.

pg_settings Output

Query :

select * from pg_settings where name = 'multixact_member_buffers';

Result :

name            | multixact_member_buffers
setting         | 32
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the size of the dedicated buffer pool used for the MultiXact member cache.
extra_desc      | 
context         | postmaster
vartype         | integer
source          | default
min_val         | 16
max_val         | 131072
enumvals        | 
boot_val        | 32
reset_val       | 32
sourcefile      | 
sourceline      | 
pending_restart | f

32 × 8kB = 256kB

Stores transaction IDs that belong to a MultiXact group.

This becomes important during concurrent row locking.

7. notify_buffers

Used by PostgreSQL’s LISTEN/NOTIFY feature.

pg_settings Output

Query :

select * from pg_settings where name = 'notify_buffers';

Result :

name            | notify_buffers
setting         | 16
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the size of the dedicated buffer pool used for the LISTEN/NOTIFY message cache.
extra_desc      | 
context         | postmaster
vartype         | integer
source          | default
min_val         | 16
max_val         | 131072
enumvals        | 
boot_val        | 16
reset_val       | 16
sourcefile      | 
sourceline      | 
pending_restart | f

16 × 8kB = 128kB

Purpose

Caches notification messages sent between sessions.

Useful for event-driven applications.

8. serializable_buffers

Used for Serializable transaction tracking.

pg_settings Output

Query :

select * from pg_settings where name = 'serializable_buffers';

Result :

name            | serializable_buffers
setting         | 32
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the size of the dedicated buffer pool used for the serializable transaction cache.
extra_desc      | 
context         | postmaster
vartype         | integer
source          | default
min_val         | 16
max_val         | 131072
enumvals        | 
boot_val        | 32
reset_val       | 32
sourcefile      | 
sourceline      | 
pending_restart | f

32 × 8kB = 256kB

Purpose

Tracks conflicts between transactions running under the SERIALIZABLE isolation level.

9. subtransaction_buffers

Used for subtransactions.

Subtransactions happen when using savepoints or nested transaction logic.

pg_settings Output

Query :

select * from pg_settings where name = 'subtransaction_buffers';

Result :

name            | subtransaction_buffers
setting         | 32
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the size of the dedicated buffer pool used for the subtransaction cache.
extra_desc      | 0 means use a fraction of "shared_buffers".
context         | postmaster
vartype         | integer
source          | default
min_val         | 0
max_val         | 131072
enumvals        | 
boot_val        | 0
reset_val       | 32
sourcefile      | 
sourceline      | 
pending_restart | f

32 × 8kB = 256kB

Purpose

Caches metadata related to savepoints and subtransactions.

10. transaction_buffers

Used for transaction status caching.

This is tied to pg_xact, which stores commit state information.

pg_settings Output

Query :

select * from pg_settings where name = 'transaction_buffers';

Result :

name            | transaction_buffers
setting         | 32
unit            | 8kB
category        | Resource Usage / Memory
short_desc      | Sets the size of the dedicated buffer pool used for the transaction status cache.
extra_desc      | 0 means use a fraction of "shared_buffers".
context         | postmaster
vartype         | integer
source          | default
min_val         | 0
max_val         | 131072
enumvals        | 
boot_val        | 0
reset_val       | 32
sourcefile      | 
sourceline      | 
pending_restart | f

32 × 8kB = 256kB

Purpose

Tracks whether transactions are committed, aborted, or still running.

Why Some Values Are Zero or Negative

Some parameters use automatic sizing.

Examples:

commit_timestamp_buffers = 0
subtransaction_buffers = 0
transaction_buffers = 0
wal_buffers = -1

This means PostgreSQL calculates a suitable value automatically based on available memory or shared_buffers.

That is why your pg_settings output shows actual runtime values like 32 or 512.

Which Buffers Matter Most for Performance Tuning?

For most production workloads, focus on:

  • shared_buffers
  • wal_buffers
  • work_mem
  • maintenance_work_mem
  • effective_cache_size

The other buffer settings are usually fine at defaults unless you are handling specific workloads.

Looking inside postgresql.conf can teach much more than just configuration tuning. It exposes PostgreSQL architecture.

From these buffer settings alone, we can learn that PostgreSQL contains dedicated subsystems for:

  • Data caching
  • WAL processing
  • Transaction state management
  • Subtransactions
  • Row locking metadata
  • Notifications
  • Serializable conflict detection
  • Internal SLRU caches

This is exactly why exploring PostgreSQL internals through configuration files and pg_settings is valuable for deeper database research.

Many PostgreSQL users know only shared_buffers, temp_buffers, and wal_buffers. But PostgreSQL uses several specialized buffer pools behind the scenes to support reliability, concurrency, and performance.

Understanding these settings gives a clearer picture of how PostgreSQL really works internally.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message