Skip to content
EL
Contents

Write-ahead logging

Should we trade durability for speed?

DecisionAdvanced3 min read10 min hands-on#durability#operations

The idea in 30 seconds

Two settings make writes much faster and are not the same thing. synchronous_commit = off can lose the last fraction of a second of commits in a crash, but never corrupts anything, and can be set per transaction. fsync = off can corrupt the whole database beyond repair after a power failure. The first is a business decision; the second almost never is.

Helps to know first: How a table is stored on disk

On this page

The situation

An event-ingestion service writes one row per incoming event, each in its own transaction, and it is falling behind at peak. An AI assistant opened a pull request.

Review taskSpeed up ingestion

Pull request: “Commits are the bottleneck. Turn off the disk syncing.”

# postgresql.conf
fsync = off
synchronous_commit = off

Would you approve it? Write the review you would leave.

Your call

How to decide

Never turn off fsync on a database you cannot recreate from scratch. It risks corruption, not just loss.

Use synchronous_commit = off where losing the last moments of data is acceptable, and set it only where that is true: per transaction or per session, not for the whole server.

Try batching first. Fewer, larger transactions reduce flushes without weakening any guarantee.

Know what your storage really does on a flush. Measure commit latency on the production hardware; on our laptop the honest flush cost 145 times the default.

Check yourself

  1. What is the worst case after a crash with synchronous_commit = off, and with fsync = off?

    Show answer

    With asynchronous commit, the most recent transactions are lost but the database is consistent. With fsync off, the data files can be corrupted beyond repair.

  2. How would you make only the ingestion inserts asynchronous?

    Show answer

    SET LOCAL synchronous_commit = off inside those transactions, or SET synchronous_commit = off in the ingestion service’s sessions. Other work keeps the server default.

  3. Why does batching help without risking any data?

    Show answer

    The commit cost is a log flush per transaction. Putting many inserts in one transaction pays one flush for all of them, and each commit is still fully durable.

Finished reading?

Saved in this browser only.

Sources

Where each claim on this page comes from.

  1. 1.
    PostgreSQL documentation: 28.4 Asynchronous Commit
    Primary· §28.4 Asynchronous Commit

    Asynchronous commit risks losing the most recent transactions in a crash, not data corruption; recovery replays WAL up to the last flushed record in commit order; it can be chosen per transaction.

  2. 2.
    PostgreSQL documentation: 19.5 Write Ahead Log
    Primary· §19.5 Write Ahead Log: fsync

    Turning fsync off can cause unrecoverable data corruption after a power failure or system crash; it is only advisable when the whole database can easily be recreated; high-quality hardware alone is not a justification.

Go further

What to read next, and why it is worth the time.

  1. 1.
    PostgreSQL documentation: 28.4 Asynchronous Commit
    Primary· §28.4

    Explains exactly how much can be lost with asynchronous commit and why it can never leave the database inconsistent.

Applies to PostgreSQL 18. Draft: not yet fact-checked end to end.