Article

PostgreSQL min_wal_size: recycled capacity versus retained history

min_wal_size sets a floor for recycling WAL files for future writes. It serves a different purpose from retaining history for standbys, so burst-performance tuning and replication continuity need separate decisions.

Share

Koharu's reading tip

The size of pg_wal alone cannot tell you whether a standby can catch up. Follow the distinction between reusing files and preserving the history a replica needs.

Koharu's reading tip

There can be plenty of files in pg_wal, yet a returning standby may still be unable to fetch the WAL it needs. Looking only at the directory size makes this seem contradictory.

Christophe Pettus's explanation of min_wal_size offers a useful starting point. A setting expressed in gigabytes can describe capacity for future writes without preserving readable history.

That distinction explains why tuning a batch workload and preparing for a standby outage require different settings. The configuration and monitoring details below use the PostgreSQL 18 documentation.

Recycling a WAL file changes which history it can serve

WAL records database changes. As checkpoints advance, old segments that are no longer required for recovery or other purposes can be deleted or renamed for future use. Renaming preserves reusable file space, but the file can no longer serve its previous segment to a standby. The WAL configuration documentation explains this lifecycle.

min_wal_size sets a floor for recycling. PostgreSQL also estimates future needs from WAL usage in previous checkpoint cycles, so the setting does not directly specify the directory's actual size.

A file's existence and the availability of a required piece of history are different properties. Directory size alone cannot establish a replication safety margin.

This is longstanding behavior. PostgreSQL 9.5 introduced min_wal_size and max_wal_size to replace checkpoint_segments, separating decisions about WAL allocation and what happens when files become unnecessary. The 9.5 release notes provide that historical context.

min_wal_size reduces file-creation work for the next burst

Keeping reusable files can reduce new-file creation when writes accelerate. Large batch jobs are an explicit use case in the documentation. Meanwhile, max_wal_size is a soft limit associated with automatic checkpoints, not a strict disk-usage cap. See the WAL settings.

Raising the floor does not immediately create enough files to fill it. Pettus describes a pool built by recycling previously written WAL, and reports better tail latency with a higher floor in a workload following a quiet period. Those are the author's measurements, not a universal performance guarantee. See his tests and analysis.

A useful tuning experiment compares slow responses during batch startup with WAL-file creation. In PostgreSQL 18, pg_stat_io rows with object equal to wal and context equal to init track creation I/O. Measuring WAL I/O time requires track_wal_io_timing. See the pg_stat_io definitions.

More reusable capacity also consumes disk space. If wal_recycle is disabled, the premise of retaining files for reuse does not apply. New-file creation can be faster on Copy-on-Write filesystems, so evaluate the storage environment too. See wal_recycle.

Plan standby recovery around retained history and retrieval paths

wal_keep_size sets a minimum amount of past WAL retained for streaming replication. If a standby falls further behind, a required segment may be removed. See the wal_keep_size specification.

Translating capacity into time requires a WAL generation rate. Assuming a constant 10 MiB/s, ten minutes produces 6,000 MiB, or about 5.9 GiB. This is an illustrative calculation, not a recommended setting. Real sizing must account for peaks during the outage and catch-up after the standby returns.

A replication slot associated with the standby retains WAL needed by its consumer. A stalled consumer can consequently cause pg_wal to fill the disk. An archive retrieval path provides another option: an available archived segment can supply history no longer present on the sender. See replication slots and standby WAL retrieval.

max_slot_wal_keep_size limits slot retention, but required WAL may then be removed and replication may become unable to continue. Its default, -1, imposes no retention-size limit through this setting. See the slot retention limit.

Read configuration and slot state separately

Start by inspecting settings on the WAL sender. SHOW displays current values; these statements do not change configuration. See the SHOW reference.

SQL
-- Read recycling, checkpoint, and history-retention settings.
SHOW min_wal_size;
SHOW max_wal_size;
SHOW wal_recycle;
SHOW wal_keep_size;
SHOW max_slot_wal_keep_size;

If slots are in use, inspect their state on the same sender. This read-only query targets PostgreSQL 18's pg_replication_slots. An empty result means there are no existing slots; other retention mechanisms still need separate inspection.

SQL
-- Read existing slot activity and WAL-retention headroom.
SELECT slot_name, slot_type, active, restart_lsn,
       wal_status, safe_wal_size
FROM pg_replication_slots;

safe_wal_size reports how many additional WAL bytes can be generated without putting the slot in danger of becoming lost. A NULL value is ambiguous: it can mean the slot is already lost, or that max_slot_wal_keep_size is -1. Read it alongside wal_status and the configuration. See the pg_replication_slots column definitions.

Returning to the opening question, the size of pg_wal cannot tell you whether a standby can resume from its required position. Evaluate file-creation I/O for performance, and retention settings plus retrieval paths for recovery. Separating those decisions makes it clear when increasing min_wal_size addresses the problem and when another mechanism is needed.

Source

Share

Related Articles

These articles share nearby categories or tags, so you can keep reading along the same thread.