What Is Write-Ahead Logging (WAL)?
Write-ahead logging records changes to a log before applying them to a database, making crash recovery and replication possible. Here's how it works.
Write-ahead logging (WAL) is a technique where a database records every change to an append-only log before applying that change to the actual data files on disk. If the database crashes mid-write, it can replay the log on restart and recover exactly the state it was supposed to reach — nothing lost, nothing half-applied. It’s one of the load-bearing ideas behind ACID durability, and it’s used by nearly every serious relational database under some name (PostgreSQL calls it WAL directly; others call it a redo log or transaction log).
The problem WAL solves
Applying a change directly to a database’s main data files is risky, because those files are often organized as fixed-size pages on disk, and updating one can mean rewriting several disk blocks. If the process crashes or the machine loses power midway through that write, you can end up with a page that’s neither the old version nor the new one — corrupted, with no way to tell what it was supposed to be.
Writing changes to disk purely in memory-buffered form doesn’t help either: memory is lost entirely on a crash, so anything not yet flushed to disk simply never happened as far as recovery is concerned.
WAL sidesteps both problems by separating durability from applying the change. The log entry — a compact, sequential record of what changed — gets written and flushed to disk first. Only after that succeeds does the database consider the transaction durable, even if the actual data-file update happens later, buffered in memory and flushed lazily.
How the write path works
- A transaction changes some rows. The database doesn’t touch the data files yet — it writes a log record describing the change to the WAL, which is a simple sequential file, cheap to append to and cheap to fsync.
- The WAL record is flushed to disk. Once that fsync completes, the transaction is durable — even though the actual table data in the main files might still only exist in memory.
- The change to the actual data pages happens later, batched with other changes, whenever it’s efficient to write them.
- Periodically, a checkpoint confirms that all changes up to a certain point in the log have been safely applied to the data files, so older WAL segments can be discarded — otherwise the log would grow forever.
The sequential nature of the write is what makes this fast: appending to the end of a log file is one of the cheapest possible disk operations, versus the random-access pattern of updating scattered data pages directly. That’s a large part of why WAL is a performance win, not just a safety mechanism.
Crash recovery
On restart after a crash, the database replays the WAL from the last known checkpoint: for each log record, it checks whether that change was already applied to the data files (if the crash happened after the data write but before the next checkpoint) and, if not, reapplies it. Uncommitted transactions in the log get rolled back instead of replayed. The result is that the database always comes back up in a consistent state — either a transaction’s effects are fully present, or entirely absent, never partial.
WAL and replication
Because the WAL is a complete, ordered record of every change, it turns out to be an efficient way to replicate a database, too. A replica can stream the primary’s WAL and replay it locally to stay in sync, rather than the primary needing to send full copies of changed rows through a separate mechanism. This is how database replication is commonly implemented in practice (see our piece on database replication) — the same log that exists for crash recovery doubles as the replication stream.
WAL vs no logging at all
| Write-ahead logging | Direct writes, no log | |
|---|---|---|
| Crash recovery | Replay the log to a consistent state | Data files can be left corrupted |
| Write pattern | Sequential appends (fast) | Random-access page writes (slower) |
| Enables replication | Yes, by streaming the log | Needs a separate mechanism |
| Storage overhead | Log files, until checkpointed | None |
Where this shows up day to day
Most application developers never interact with WAL directly, but its behavior explains some things you’ll run into: why a database’s data directory includes log segment files you shouldn’t delete by hand, why replication lag is usually measured in “bytes of WAL behind,” and why an aggressive fsync-per-commit setting trades throughput for durability guarantees. It also underpins database isolation levels indirectly — the log is what lets a database undo a transaction cleanly if it needs to abort partway through.
The takeaway
Write-ahead logging makes durability cheap by turning “did this transaction survive a crash” into “is this log record safely on disk,” which is a fast sequential write, instead of “are these scattered data pages fully updated,” which is a slow random one. The log gets replayed on recovery to rebuild a consistent state, and as a side effect, that same ordered stream of changes is what most databases use to keep replicas in sync.
Tagged
Keep reading
The Lycoris Team · · 5 min read What Is a Stored Procedure? SQL Logic in the Database
A stored procedure is precompiled SQL saved inside the database and invoked by name, cutting network round trips and centralizing business logic.
The Lycoris Team · · 5 min read What Is a Database Trigger?
A database trigger is a procedure that runs automatically on an insert, update, or delete — enforcing rules the application layer can't guarantee.
The Lycoris Team · · 4 min read Primary Key vs Foreign Key vs Unique Constraint
Primary keys identify a row, foreign keys link one table to another, and unique constraints just prevent duplicates. How the three differ in SQL.