{
    "slug": "write_ahead_log",
    "term": "Write-Ahead Log (WAL)",
    "category": "database",
    "difficulty": "advanced",
    "short": "A durability technique where changes are written to an append-only log before being applied to the database — if the system crashes, the log is replayed to restore the database to a consistent state.",
    "long": "The Write-Ahead Log (WAL) is the primary mechanism for crash recovery and replication in databases. Before modifying any data pages, the database writes a log record describing the change to a sequential append-only file. On crash recovery, the database reads the WAL from the last checkpoint forward and re-applies all committed transactions. Uncommitted transactions are rolled back. This 'write log first, then data' rule (the WAL protocol) ensures durability — once a transaction is acknowledged, its log record is on disk even if the data pages are still in memory. PostgreSQL exposes WAL directly: pg_wal/ contains the log files; WAL streaming is the mechanism for replication; logical decoding reads WAL for change data capture.",
    "aliases": [
        "WAL",
        "write-ahead logging",
        "redo log",
        "transaction log",
        "pg_wal"
    ],
    "tags": [
        "database-internals",
        "durability",
        "crash-recovery",
        "replication",
        "postgresql"
    ],
    "misconception": "WAL only exists in PostgreSQL. All serious databases use some form of write-ahead logging — MySQL InnoDB uses a redo log, SQLite uses a WAL journal, MongoDB uses an oplog. The concept is universal; the implementation details differ.",
    "why_it_matters": "WAL explains how databases survive crashes without losing committed data, how streaming replication works (followers replay the primary's WAL), and how change data capture (CDC) tools like Debezium read database changes without impacting queries. Understanding WAL helps when configuring synchronous vs asynchronous replication trade-offs.",
    "common_mistakes": [
        "Setting fsync=off in production for performance — this is the default for many Docker-based PostgreSQL setups; it causes database corruption on power loss or OOM kills.",
        "Not archiving WAL for point-in-time recovery — without WAL archiving, you can only restore to your last base backup, not to any moment in between.",
        "Underestimating WAL volume during high write periods — replication lag grows when WAL is generated faster than replicas can apply it; monitor pg_replication_slots.",
        "Using logical replication slots without monitoring — unconsumed logical replication slots cause WAL to accumulate indefinitely, filling disk."
    ],
    "when_to_use": [
        "WAL is the mechanism behind database crash recovery and replication — understanding it helps debug replication lag and disk I/O spikes.",
        "Enable WAL mode in SQLite for better concurrent read performance."
    ],
    "avoid_when": [
        "Do not disable WAL/redo logging in production databases — it is the primary durability guarantee.",
        "Avoid extremely large WAL files by tuning checkpoint frequency — unbounded WAL growth increases crash recovery time."
    ],
    "related": [
        "db_transactions",
        "db_replication_types",
        "change_data_capture",
        "db_isolation_levels",
        "acid_properties"
    ],
    "prerequisites": [],
    "refs": [
        "https://www.postgresql.org/docs/current/wal-intro.html",
        "https://www.postgresql.org/docs/current/runtime-config-wal.html"
    ],
    "bad_code": "# ❌ PostgreSQL settings that sacrifice durability for speed\n# Dangerous in production — data loss on crash\nfsync = off                  # Disables OS fsync — data NOT guaranteed on disk\nsynchronous_commit = off     # Commits return before WAL written to disk\nfull_page_writes = off       # Risks torn page corruption after crash",
    "good_code": "# ✅ PostgreSQL WAL settings — durability vs performance\n# Production defaults (safe):\nfsync = on                   # Ensure WAL is on disk before ack\nsynchronous_commit = on      # Default — safest\nfull_page_writes = on        # Protects against torn page writes\nwal_level = replica          # Required for streaming replication\narchive_mode = on            # Enable WAL archiving for PITR\narchive_command = 'cp %p /mnt/wal-archive/%f'\n\n# For read replicas:\n# primary_conninfo in recovery.conf\n# Replica streams WAL from primary and applies it continuously",
    "quick_fix": "In PostgreSQL, set 'synchronous_commit = on' for durability (default) or 'off' for performance with a risk of losing the last few milliseconds of commits on crash. Never disable fsync unless you're okay with data corruption on power loss.",
    "effort": "medium",
    "created": "2026-03-23",
    "updated": "2026-03-31",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/write_ahead_log",
        "html_url": "https://codeclaritylab.com/glossary/write_ahead_log",
        "json_url": "https://codeclaritylab.com/glossary/write_ahead_log.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Write-Ahead Log (WAL)](https://codeclaritylab.com/glossary/write_ahead_log) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/write_ahead_log"
            }
        }
    }
}