A transaction commits. Your application gets an acknowledgement and moves on. Two seconds later the power fails. When the machine comes back, is the data there?
It should be, and the mechanism that makes it so is write-ahead logging — one of those ideas that sounds almost too simple to be the answer. Before modifying any data, write down what you are about to do. Make sure that record is genuinely on disk. Only then touch the data itself. If you crash at any point, the log tells you what was in progress and what to do about it.
What changed in 2026
- Managed databases hid the knobs but not the consequences. Most teams no longer tune WAL settings directly, which makes it easier to be surprised by the behaviour they inherit — particularly around replication lag and storage growth.
- Change data capture went mainstream. Reading the WAL to stream changes into other systems moved from a specialist technique to a default integration pattern, which means the log now has consumers beyond the database itself.
- Storage economics shifted the defaults. Faster commit latency on modern SSDs made synchronous commit affordable for workloads that previously felt obliged to weaken it.
- Point-in-time recovery became an expectation. Continuous archiving of log segments is standard in managed offerings, and "restore to 14:32 yesterday" is now a normal request rather than an exotic one.
The core mechanism
The ordering is the whole idea. Consider updating a row:
- Write a log record describing the change — the transaction, the page, the before and after.
- Flush that record to durable storage.
- Acknowledge the commit to the client.
- Modify the actual data page, whenever convenient. Often much later, in memory first.
Step 2 before step 3 is what makes the promise true. Step 4 being lazy is what makes it fast.
The performance win is not obvious at first glance — you are writing more, not less. It works because log writes are sequential appends to one file, while data pages are scattered across the disk. Turning many random writes into one sequential write and deferring the random part is the trade, and it is a very good one.
The dirty pages get written out eventually, in the background, in an order the storage layer likes. If the machine crashes before that happens, the log has everything needed to redo the work.
Durability means fsync
The subtlety that catches people: writing to a file does not put data on a disk. It puts data in an operating system buffer, which is flushed on the OS's schedule. A crash between those points loses it, and your application already told the user the write succeeded.
Durability requires an explicit flush — fsync or an equivalent — and waiting for it to return. That wait is real; it is the single largest contributor to commit latency in most transactional workloads.
This is what a "synchronous commit" setting controls. Turn it off and commits return as soon as the log record is in memory, which is dramatically faster and means a crash can lose the last fraction of a second of transactions. Whether that is acceptable is a business question, not a technical one. Losing analytics events is different from losing payments, and the honest version of this decision names the window and the data rather than treating it as a generic throughput setting.
Group commit softens the trade without weakening it: batch several transactions into one flush, amortising the expensive part across all of them. Most databases do this automatically under concurrent load, which is why write throughput often improves with more concurrent writers rather than less.
Checkpoints, replication, and recovery
Checkpoints are what stop the log from being infinite. At a checkpoint the database flushes dirty pages and records that everything before this point is safely in the data files. Recovery then only needs to replay from the last checkpoint rather than from the beginning of time. Frequent checkpoints mean fast recovery and more steady I/O; infrequent ones mean less routine work and a longer restart. That is the entire tuning tradeoff.
Replication falls out almost for free. A replica that receives the log stream and applies it ends up with an identical database — the WAL is already a precise, ordered description of every change. This is why physical replication is typically the cheapest form to operate, and why replication lag is measured in log position rather than in rows. Read replicas explained covers the consistency implications.
Point-in-time recovery is the same trick with a time axis. Keep a base backup plus every log segment since, and you can replay to any moment. Recovering from an accidental DELETE at 14:31 means restoring the base and replaying to 14:30 — which is the only remedy for a mistake that replication faithfully copied to every replica.
Common mistakes
- Assuming replication is a backup. It replicates your mistakes instantly. Backups plus archived logs are what let you go back.
- Disabling synchronous commit without naming the acceptable loss window. A throughput decision quietly becoming a durability decision.
- Not monitoring log growth. A stalled replica or an inactive replication slot prevents log recycling, and the volume fills. This is a common and entirely avoidable outage.
- Checkpointing too aggressively. Constant flushing produces I/O spikes that show up as latency for everyone.
- Trusting storage that lies about flushes. Some consumer drives and virtualised layers acknowledge a flush before it completes, which silently voids the guarantee.
- Forgetting the log needs its own headroom. Bulk operations generate far more log than their data size suggests.
FAQ
Is SQLite's WAL mode the same thing?
Same principle, different scale. It brings sequential-append durability and lets readers proceed during writes, which is the main practical benefit — see Postgres vs SQLite for where each fits.
Why is my log directory so large?
Usually a replication slot or archiving process that has stopped consuming. The database keeps segments until every consumer has them, so one stuck reader pins the whole series.
Does this apply to NoSQL databases?
Broadly yes. Most durable stores use a log-first design under some other name — commit log, journal, oplog. The ordering guarantee is the same idea.
How does it affect write performance?
It improves it, counter-intuitively, by converting random writes to sequential ones. The flush wait is the cost, and group commit amortises it under concurrency.
Where to go next
For how the log feeds other systems, read read replicas explained. For the storage layer that determines how expensive those flushes are, database indexing explained covers what else competes for the same I/O, and database sharding explained covers what happens to durability guarantees once one machine is no longer enough.