Write-Ahead Logging (WAL) is the backbone of PostgreSQL’s reliability. Every change made to the database is first written into WAL before it touches the actual data files. This guarantees durability, enables crash recovery, and powers replication.
When you explore WAL parameters using SHOW and pg_settings, you are essentially looking at how PostgreSQL controls:
- Memory buffering
- Disk write behavior
- Replication flow
- Recovery efficiency
Let’s get into each PostgreSQL configuration parameter related to the write ahead log (WAL)
Wal_block_size
SHOW wal_block_size;
Result :
wal_block_size
----------------
8192
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_block_size';
Result :
-[ RECORD 1 ]---+---------------------------------------------
name | wal_block_size
setting | 8192
unit |
category | Preset Options
short_desc | Shows the block size in the write ahead log.
extra_desc |
context | internal
vartype | integer
source | default
min_val | 8192
max_val | 8192
enumvals |
boot_val | 8192
reset_val | 8192
sourcefile |
sourceline |
pending_restart | f
The wal_block_size defines the fundamental unit in which WAL data is written. PostgreSQL organizes WAL into fixed-size blocks, and each record is stored inside these blocks. Here, the size of the wal block is 8192 bytes (8 KB), which matches the default PostgreSQL page size.
This parameter is not configurable at runtime or even via postgresql.conf. It is hardcoded during the build process. That means once your PostgreSQL instance is initialized, this value is fixed for the lifetime of the cluster.
Internally, WAL records are packed into these blocks, and the system ensures alignment and consistency at this level. This is important for crash recovery because PostgreSQL reads WAL block by block when replaying changes.
Wal_buffers
SHOW wal_buffers;
Result
wal_buffers
-------------
4MB
(1 row)
Metadata from pg_settings
postgres=# select * from pg_settings where name = 'wal_buffers';
Result
-[ RECORD 1 ]---+---------------------------------------------------------------
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
The wal_buffers parameter controls how much shared memory is allocated for temporarily holding WAL data before it is flushed to disk. Every transaction generates WAL records, and instead of writing each change directly to disk, PostgreSQL first accumulates them in these buffers.
By default, it is set to 4 MB. Internally, this means PostgreSQL can batch multiple WAL records together and write them more efficiently.
If this buffer is too small, PostgreSQL will be forced to flush WAL more frequently, increasing disk I/O and reducing performance. If it is sufficiently large, more WAL can be accumulated and written in fewer operations, improving throughput.
Wal_compression
SHOW wal_compression;
Result
wal_compression
-----------------
off
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_compression';
Result
-[ RECORD 1 ]---+-----------------------------------------------------------------------
name | wal_compression
setting | off
unit |
category | Write-Ahead Log / Settings
short_desc | Compresses full-page writes written in WAL file with specified method.
extra_desc |
context | superuser
vartype | enum
source | default
min_val |
max_val |
enumvals | {pglz,lz4,zstd,on,off}
boot_val | off
reset_val | off
sourcefile |
sourceline |
pending_restart | f
The wal_compression parameter determines whether PostgreSQL compresses full-page images before writing them to WAL. Full-page writes occur after checkpoints to ensure consistency during crash recovery.
When compression is disabled, these full-page writes consume more disk space and I/O bandwidth. When enabled, PostgreSQL compresses these pages using algorithms like pglz, lz4, or zstd.
In modern systems where CPU is not the bottleneck, enabling compression (especially lz4 or zstd) can significantly reduce WAL size.
This parameter is particularly useful in:
- Write-heavy systems
- Systems with limited disk bandwidth
- Replication setups where WAL transfer size matters
Wal_consistency_checking
show wal_consistency_checking ;
Result :
wal_consistency_checking
--------------------------
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_consistency_checking';
Result :
name | wal_consistency_checking
setting |
unit |
category | Developer Options
short_desc | Sets the WAL resource managers for which WAL consistency checks are done.
extra_desc | Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay.
context | superuser
vartype | string
source | default
min_val |
max_val |
enumvals |
boot_val |
reset_val |
sourcefile |
sourceline |
pending_restart | f
This parameter is mainly intended for debugging and development purposes. It forces PostgreSQL to log additional information into WAL and perform consistency checks during WAL replay.
When enabled, PostgreSQL logs full-page images and verifies that applying WAL records produces consistent results. This is useful when developing or modifying PostgreSQL internals, especially in WAL-related code paths.
However, this comes with significant overhead:
- Increased WAL size
- Additional CPU work
- Slower performance
In production environments, this parameter is typically left empty or disabled. It is mainly used by PostgreSQL developers or contributors when validating correctness.
Wal_decode_buffer_size
SHOW wal_decode_buffer_size;
Result :
wal_decode_buffer_size
------------------------
512kB
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_decode_buffer_size';
Result :
name | wal_decode_buffer_size
setting | 524288
unit | B
category | Write-Ahead Log / Recovery
short_desc | Buffer size for reading ahead in the WAL during recovery.
extra_desc | Maximum distance to read ahead in the WAL to prefetch referenced data blocks.
context | postmaster
vartype | integer
source | default
min_val | 65536
max_val | 1073741823
enumvals |
boot_val | 524288
reset_val | 524288
sourcefile |
sourceline |
pending_restart | f
This parameter controls how much WAL data PostgreSQL reads ahead during recovery or logical decoding. Instead of reading WAL strictly sequentially in small chunks, PostgreSQL can prefetch a larger portion into memory.
This improves performance during:
- Crash recovery
- Streaming replication replay
- Logical decoding
A larger buffer allows PostgreSQL to reduce disk reads and process WAL more efficiently. However, increasing it too much may consume unnecessary memory.
wal_init_zero
SHOW wal_init_zero;
Result
wal_init_zero
---------------
on
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_init_zero';
Result :
name | wal_init_zero
setting | on
unit |
category | Write-Ahead Log / Settings
short_desc | Writes zeroes to new WAL files before first use.
extra_desc |
context | superuser
vartype | bool
source | default
min_val |
max_val |
enumvals |
boot_val | on
reset_val | on
sourcefile |
sourceline |
pending_restart | f
The wal_init_zero parameter ensures that new WAL segment files are initialized with zeros before use. This guarantees that the file does not contain leftover or garbage data from previous disk usage.
This is important for:
- Data integrity
- Predictable file behavior
- Avoiding unexpected read errors
Although zero-initialization adds a small overhead when creating new WAL files, it improves safety and reliability.
In almost all cases, this should remain enabled.
Wal_keep_size
SHOW wal_keep_size;
Result :
wal_keep_size
---------------
0
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_keep_size';
Result :
name | wal_keep_size
setting | 0
unit | MB
category | Replication / Sending Servers
short_desc | Sets the size of WAL files held for standby servers.
extra_desc |
context | sighup
vartype | integer
source | default
min_val | 0
max_val | 2147483647
enumvals |
boot_val | 0
reset_val | 0
sourcefile |
sourceline |
pending_restart | f
This parameter defines how much WAL PostgreSQL should retain to support standby servers. When set to 0, PostgreSQL does not reserve extra WAL beyond what is required for normal operation.
In replication setups, if WAL files are removed before a standby server has consumed them, replication will break.
Setting a non-zero value ensures that a minimum amount of WAL is always retained, preventing such failures.
wal_level
Show wal_level;
Result :
wal_level
-----------
replica
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_level';
Result :
name | wal_level
setting | replica
unit |
category | Write-Ahead Log / Settings
short_desc | Sets the level of information written to the WAL.
extra_desc |
context | postmaster
vartype | enum
source | default
min_val |
max_val |
enumvals | {minimal,replica,logical}
boot_val | replica
reset_val | replica
sourcefile |
sourceline |
pending_restart | f
The wal_level parameter determines how much information PostgreSQL writes into WAL.
There are three levels:
- minimal: minimal logging, no replication support
- replica: supports physical replication
- logical: supports logical replication and decoding
Increasing the level increases WAL volume because more information is logged. However, it enables advanced features like logical replication.
This is one of the most important WAL parameters when designing system architecture.
Wal_log_hints
SHOW wal_log_hints;
Result :
wal_log_hints
---------------
off
(1 row)
Metadata from pg_settings
Select * from pg_settings where name = 'wal_log_hints';
Result :
name | wal_log_hints
setting | off
unit |
category | Write-Ahead Log / Settings
short_desc | Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification.
extra_desc |
context | postmaster
vartype | bool
source | default
min_val |
max_val |
enumvals |
boot_val | off
reset_val | off
sourcefile |
sourceline |
pending_restart | f
This parameter forces PostgreSQL to log full-page writes even for hint bit updates, which are normally not critical changes.
Hint bits are used internally to mark tuple visibility and optimize performance. Normally, they are not WAL-logged to reduce overhead.
However, enabling wal_log_hints ensures these updates are also logged, which is required for tools like pg_rewind.
This parameter:
- Increases WAL size
- Improves recovery tooling compatibility
wal_receiver_create_temp_slot
SHOW wal_receiver_create_temp_slot;
Result
wal_receiver_create_temp_slot
-------------------------------
off
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_receiver_create_temp_slot';
Result :
name | wal_receiver_create_temp_slot
setting | off
unit |
category | Replication / Standby Servers
short_desc | Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured.
extra_desc |
context | sighup
vartype | bool
source | default
min_val |
max_val |
enumvals |
boot_val | off
reset_val | off
sourcefile |
sourceline |
pending_restart | f
This parameter allows a standby server to automatically create a temporary replication slot if no permanent slot is configured.
Replication slots ensure that WAL files are not removed until a standby has consumed them.
Temporary slots:
- Exist only during the session
- Do not persist after restart
This parameter simplifies replication setup but is usually disabled in controlled production environments where permanent slots are preferred.
Wal_receiver_status_interval
SHOW wal_receiver_status_interval;
Result :
wal_receiver_status_interval
------------------------------
10s
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_receiver_status_interval';
Result :
name | wal_receiver_status_interval
setting | 10
unit | s
category | Replication / Standby Servers
short_desc | Sets the maximum interval between WAL receiver status reports to the sending server.
extra_desc |
context | sighup
vartype | integer
source | default
min_val | 0
max_val | 2147483
enumvals |
boot_val | 10
reset_val | 10
sourcefile |
sourceline |
pending_restart | f
This defines how often the standby server sends status updates to the primary.
These updates include:
- Replay position
- Write position
- Flush status
Frequent updates improve monitoring accuracy and allow the primary to manage WAL retention more effectively.
However, very low values can increase network overhead.
Wal_receiver_timeout
SHOW wal_receiver_timeout;
Result :
wal_receiver_timeout
----------------------
1min
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_receiver_timeout';
Result :
name | wal_receiver_timeout
setting | 60000
unit | ms
category | Replication / Standby Servers
short_desc | Sets the maximum wait time to receive data from the sending server.
extra_desc | 0 disables the timeout.
context | sighup
vartype | integer
source | default
min_val | 0
max_val | 2147483647
enumvals |
boot_val | 60000
reset_val | 60000
sourcefile |
sourceline |
pending_restart | f
This parameter specifies how long a standby waits before considering the connection to the primary lost.
If no WAL data is received within this time, PostgreSQL assumes a failure.
This is important for:
- Detecting network issues
- Triggering failover mechanisms
Wal_recycle
SHOW wal_recycle;
Result :
wal_recycle
-------------
on
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_recycle';
Result :
name | wal_recycle
setting | on
unit |
category | Write-Ahead Log / Settings
short_desc | Recycles WAL files by renaming them.
extra_desc |
context | superuser
vartype | bool
source | default
min_val |
max_val |
enumvals |
boot_val | on
reset_val | on
sourcefile |
sourceline |
pending_restart | f
Instead of deleting old WAL files and creating new ones, PostgreSQL can recycle them by renaming and reusing existing files.
This improves performance by:
- Reducing filesystem operations
- Avoiding repeated file creation
This is almost always beneficial and should remain enabled.
Wal_retrieve_retry_interval
SHOW wal_retrieve_retry_interval;
Result
wal_retrieve_retry_interval
-----------------------------
5s
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_retrieve_retry_interval';
Result :
name | wal_retrieve_retry_interval
setting | 5000
unit | ms
category | Replication / Standby Servers
short_desc | Sets the time to wait before retrying to retrieve WAL after a failed attempt.
extra_desc |
context | sighup
vartype | integer
source | default
min_val | 1
max_val | 2147483647
enumvals |
boot_val | 5000
reset_val | 5000
sourcefile |
sourceline |
pending_restart | f
When a standby fails to retrieve WAL data, it waits for this interval before retrying.
This prevents continuous retry loops and reduces unnecessary load.
A shorter interval improves responsiveness, while a longer interval reduces retry overhead.
Wal_segment_size
SHOW wal_segment_size;
Result :
wal_segment_size
------------------
16MB
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_segment_size';
Result :
name | wal_segment_size
setting | 16777216
unit | B
category | Preset Options
short_desc | Shows the size of write ahead log segments.
extra_desc |
context | internal
vartype | integer
source | default
min_val | 1048576
max_val | 1073741824
enumvals |
boot_val | 16777216
reset_val | 16777216
sourcefile |
sourceline |
pending_restart | f
This defines the size of each WAL file segment. PostgreSQL divides WAL into multiple segment files of this size.
This value is fixed at cluster initialization and cannot be changed afterward.
Larger segments:
- Reduce number of files
- Improve sequential I/O
Smaller segments:
- Allow finer-grained archiving
- Easier WAL management
Wal_sender_timeout
SHOW wal_sender_timeout;
Result
wal_sender_timeout
--------------------
1min
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_sender_timeout';
Result :
-[ RECORD 1 ]---+---------------------------------------------------
name | wal_sender_timeout
setting | 60000
unit | ms
category | Replication / Sending Servers
short_desc | Sets the maximum time to wait for WAL replication.
extra_desc |
context | user
vartype | integer
source | default
min_val | 0
max_val | 2147483647
enumvals |
boot_val | 60000
reset_val | 60000
sourcefile |
sourceline |
pending_restart | f
This parameter defines how long the primary waits for a response from a standby.
If no response is received, the connection is considered broken.
It helps detect:
- Standby crashes
- Network failures
wal_skip_threshold
SHOW wal_skip_threshold;
Result :
wal_skip_threshold
--------------------
2MB
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_skip_threshold';
Result :
name | wal_skip_threshold
setting | 2048
unit | kB
category | Write-Ahead Log / Settings
short_desc | Minimum size of new file to fsync instead of writing WAL.
extra_desc |
context | user
vartype | integer
source | default
min_val | 0
max_val | 2147483647
enumvals |
boot_val | 2048
reset_val | 2048
sourcefile |
sourceline |
pending_restart | f
This parameter determines when PostgreSQL skips writing WAL for certain large operations and instead performs direct file synchronization.
This can improve performance for bulk operations by reducing WAL overhead.
Wal_summary_keep_time
SHOW wal_summary_keep_time;
Result :
wal_summary_keep_time
-----------------------
10d
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_summary_keep_time';
Result :
name | wal_summary_keep_time
setting | 14400
unit | min
category | Write-Ahead Log / Summarization
short_desc | Time for which WAL summary files should be kept.
extra_desc | 0 disables automatic summary file deletion.
context | sighup
vartype | integer
source | default
min_val | 0
max_val | 35791394
enumvals |
boot_val | 14400
reset_val | 14400
sourcefile |
sourceline |
pending_restart | f
This controls how long WAL summary files are retained.
These summaries are useful for:
- Monitoring
- Analysis
- Debugging
Keeping them longer allows better insight into historical WAL activity.
Wal_sync_method
SHOW wal_sync_method;
Result :
wal_sync_method
-----------------
fdatasync
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_sync_method';
Result :
name | wal_sync_method
setting | fdatasync
unit |
category | Write-Ahead Log / Settings
short_desc | Selects the method used for forcing WAL updates to disk.
extra_desc |
context | sighup
vartype | enum
source | default
min_val |
max_val |
enumvals | {fsync,fdatasync,open_sync,open_datasync}
boot_val | fdatasync
reset_val | fdatasync
sourcefile |
sourceline |
pending_restart | f
This parameter determines how WAL data is flushed to disk.
Different methods interact differently with the operating system.
fdatasync is commonly used because it balances performance and safety.
Choosing the right method depends on:
- OS behavior
- Filesystem type
Wal_writer_delay
SHOW wal_writer_delay;
Result
wal_writer_delay
------------------
200ms
(1 row)
Metadata from pg_settings
select * from pg_settings where name = 'wal_writer_delay';
Result :
name | wal_writer_delay
setting | 200
unit | ms
category | Write-Ahead Log / Settings
short_desc | Time between WAL flushes performed in the WAL writer.
extra_desc |
context | sighup
vartype | integer
source | default
min_val | 1
max_val | 10000
enumvals |
boot_val | 200
reset_val | 200
sourcefile |
sourceline |
pending_restart | f
This defines how frequently the WAL writer process flushes WAL buffers to disk.
Lower values:
- Reduce latency
- Increase disk activity
Higher values:
- Improve batching
- Reduce disk writes
Wal_writer_flush_after
SHOW wal_writer_flush_after;
Result :
wal_writer_flush_after
------------------------
1MB
(1 row)
Metadata from pg_settings
select * from pg_settings where name ='wal_writer_flush_after';
Result :
name | wal_writer_flush_after
setting | 128
unit | 8kB
category | Write-Ahead Log / Settings
short_desc | Amount of WAL written out by WAL writer that triggers a flush.
extra_desc |
context | sighup
vartype | integer
source | default
min_val | 0
max_val | 2147483647
enumvals |
boot_val | 128
reset_val | 128
sourcefile |
sourceline |
pending_restart | f
This parameter triggers a flush after a certain amount of WAL has been written.
It ensures that WAL is not kept in memory for too long, improving durability.
WAL configuration is not just a set of parameters. It is a system that balances durability, performance, and scalability.
Understanding WAL configuration parameters is essential when you are working on performance tuning and reliability in PostgreSQL, especially in systems like Odoo, where write operations are frequent and critical. Each WAL setting plays a specific role and some control how data is written, others influence replication behavior, and a few directly impact durability and crash recovery.
Rather than changing everything at once, the key is to approach tuning with clarity: identify your workload pattern, observe system behavior, and adjust only the parameters that align with your goals. For example, high-write systems may benefit from optimizing buffer and compression settings, while replicated environments require careful attention to WAL retention and sender/receiver configurations.
In the end, WAL is not just an internal mechanism. It is the backbone of PostgreSQL’s reliability. A well-tuned WAL setup can significantly improve performance, reduce disk overhead, and ensure data safety without unnecessary resource usage.