How a Checkpoint Works Internally in PostgreSQL
The Checkpointer performs the following steps

The Checkpointer performs the following steps
Marks a Safe Point (Redo LSN): PostgreSQL identifies a position in the WAL called the Redo LSN and writes a
CKPT_STARTrecord. If a crash happens later, the database knows it only needs to recover data starting from this exact point forward.Writes “Dirty Pages” Slowly: It identifies all data changed in memory (dirty pages) and writes them to the operating system cache. It does this slowly (Spreading) to prevent the hard drive from freezing up for users.
Forces Data to Be Permanent (
fsync): The checkpointer issues anfsync()call to ensure that all modified database pages written from the shared buffer cache to the operating system’s page cache are safely flushed to the database files on persistent storage.Writes a Success Receipt: A
CKPT_ENDrecord is written to the WAL to seal the process. Only after this succeeds is thepg_controlfile updated with the Redo LSN (from Step 1) to officially confirm to the entire system that the checkpoint finished safely.- Triggers WAL Cleanup (Recycling/Removal Decision)
Now that data is safely on disk, old WAL files are no longer needed for crash recovery. However, Postgres only deletes or reuses them after checking these rules:
PostgreSQL checks:
- min_wal_size
- Keep at least this much WAL available.
- WAL files below this threshold are usually recycled instead of removed.
- max_wal_size
- If total WAL exceeds this value, PostgreSQL tries to recycle or remove old WAL files after the checkpoint.
- archive_mode / archive_command
- If WAL archiving is enabled, a WAL file cannot be removed or recycled until it has been successfully archived.
- The corresponding
.readyfile changes to.doneonly after successful archiving.
- wal_keep_size
- Prevents removal of WAL files that may still be needed by streaming replication standbys.
- slot_wal_keep_size / Replication Slots
- WAL required by any replication slot must be retained.
- If a standby has fallen behind, PostgreSQL keeps the required WAL files until the slot no longer needs them (subject to
slot_wal_keep_sizeif configured).
Crash Recovery During Instance Startup
If the database crashes during Step 2 or Step 3, the pg_control file still points to the previous successful checkpoint. Because pg_control is not updated until the very end of Step 4, Postgres knows on reboot that the current checkpoint failed, ignores it completely, and safely recovers using the older, valid checkpoint instead.