WierdX — Programming Reference All tutorials →
Developer reference · Practical tutorials · CS fundamentals
Databases & SQL

Write-Ahead Logging: How Databases Guarantee Durability

The "D" in ACID means a committed write survives power loss, a kernel panic, or a killed process. Write-ahead logging is the mechanism that actually makes that promise true, and it's older and simpler than most of the systems built on top of it.

Published July 6, 2026

The naive way to update a row would be to find its page on disk and overwrite it in place. That's dangerous: if the process crashes halfway through writing the page, you're left with a page that's neither the old version nor the new one — a torn write, potentially corrupting an index or a row that spans a page boundary. Write-ahead logging sidesteps this by never letting an in-place update be the first thing that happens. Instead, before any data page is modified, the database appends a record describing the change to a sequential log file, and only considers the transaction durable once that log record has been physically flushed to disk.

Why appending beats overwriting

A sequential append to the end of a log file is one of the cheapest operations a disk can do — no seeking, no read-modify-write of an existing page, just writing new bytes after the last ones. Random writes scattered across a multi-gigabyte table file are comparatively expensive, especially on spinning disks but even on SSDs where write amplification matters. By making the log the thing that must hit disk before a transaction is acknowledged, and letting the actual data pages catch up later on the database's own schedule, WAL turns the durability-critical path into the fast, sequential kind of I/O.

The rule that makes recovery possible

The core invariant is simple to state: a log record describing a change must reach durable storage before the data page it describes is allowed to reach durable storage. Break that ordering and you can end up with a data page reflecting a change whose log record never made it to disk — meaning if you crash right then, recovery has no way to know that change happened, but the on-disk page shows it anyway, disagreeing with what recovery reconstructs. Keeping the ordering intact means recovery always has a truthful record of everything that was durably committed, even if the data files themselves lag behind.

What happens when the database restarts after a crash

On restart, the database replays the log from the last known-good checkpoint. Committed transactions whose changes hadn't yet been written to the actual data pages get redone from the log. Transactions that were in progress but never committed get undone, using the same log records in reverse, so the data files end up looking exactly as if the crash had never interrupted anything mid-transaction. This redo-undo recovery is what lets a database come back online after a hard crash with zero data loss for anything it had actually acknowledged as committed.

-- conceptual WAL entry, not a real command
LSN=10042 txn=88 table=orders page=417
  before: status=pending
  after:  status=paid

Checkpointing keeps the log from growing forever

If the log kept every record since the database was created, recovery after a crash would mean replaying years of history. Checkpointing periodically forces all data pages modified before a certain point to actually be written to disk, and records that fact, so recovery only ever needs to replay the log starting from the most recent checkpoint rather than from the beginning of time. Tuning how often checkpoints run is a real trade-off: frequent checkpoints mean faster recovery but more background I/O competing with live traffic; infrequent checkpoints mean the opposite.

Why fsync is the detail that actually matters

None of this durability guarantee holds if the log write only reaches the operating system's page cache instead of the physical disk. A database calls fsync (or an equivalent) on the log file specifically to force the OS to flush it past any cache and confirm it's actually on durable media before returning "commit successful" to the client. Disabling or misconfiguring this call is a well-known way to get a large, misleading speedup in benchmarks that evaporates the moment a real crash happens and recently committed transactions turn out never to have actually been durable at all.