PostgreSQL's Write-Ahead Logging (WAL) is at the heart of its durability and crash recovery. If you've ever wondered how PostgreSQL ensures your data is safe even in the event of a crash, this post walks through the architecture, flow, and the actual source code that makes it work.

What is WAL?

WAL is a mechanism that ensures all changes to the database are first recorded in a log before being applied to the data files. This guarantees that even if the system crashes, PostgreSQL can recover to a consistent state.

The core idea: write the log first, apply the change second. If a crash happens between those two steps, recovery replays the log to reconstruct the correct state.

Key components

The write sequence

When a transaction commits, PostgreSQL follows this sequence:

  1. A change is initiated (INSERT, UPDATE, DELETE)
  2. A WAL record is created describing the change
  3. The record is placed in WAL buffers (XLogInsert)
  4. At commit, WAL is flushed to disk (XLogFlush)
  5. The data page change is applied
  6. On crash, StartupXLOG replays WAL records from the last checkpoint

Key source code locations

The WAL implementation lives in src/backend/access/transam/:

Key structs: XLogRecPtr (a WAL position), XLogRecord (a single WAL record), XLogCtlData (shared memory control structure).

Relevant postgresql.conf parameters

Parameter Default Purpose
wal_level replica How much information is written to WAL
wal_buffers -1 (auto) Size of WAL buffer in shared memory
wal_writer_delay 200ms How often the WAL writer flushes
max_wal_size 1GB Maximum size before a checkpoint is triggered
archive_mode off Enable WAL archiving

What I learned

Reading the PostgreSQL source alongside the documentation changes how you think about durability. The WAL code is surprisingly clean and well-commented for a system of its age. XLogInsert does less than you'd expect; most of the complexity is in the flush path and recovery.

If you want to explore the source: start with XLogInsert() in xlog.c, follow the call to XLogFlush(), then trace StartupXLOG() to see how recovery works.