Why architecture matters here
CDC via logical decoding matters because keeping downstream systems synchronized with a database is a ubiquitous need, and WAL-based CDC is the correct solution. Nearly every system has this need: a cache that must invalidate when data changes, a search index that must update, a data warehouse that must ingest changes, a microservice that must react to another's data changes, a replica that must stay current. The naive approaches all have serious flaws — polling is laggy and inefficient (repeatedly asking 'changed?'), triggers add write-path overhead and coupling (every write fires trigger logic), dual writes risk inconsistency (the database write and the downstream write can diverge on failure). CDC from the WAL sidesteps all of these: it reads the change log the database already maintains, getting every committed change in order with minimal overhead, as a stream. For the pervasive problem of database-to-downstream synchronization, WAL-based CDC is the architecturally sound answer, and it underpins modern data infrastructure (the Kafka-plus-Debezium pattern feeding everything downstream from database changes).
The WAL-leverage insight is the architectural core, and it's why CDC is efficient and correct. The write-ahead log exists for the database's own purposes — durability (changes logged before applied, so crashes are recoverable) and replication (replicas replay the WAL) — so it's an authoritative, ordered, complete record of every change the database makes, maintained regardless of CDC. Logical decoding reads this existing log: it doesn't add write-path overhead (it reads the log after the fact, not intercepting writes like triggers), it captures every change (the WAL is authoritative — nothing committed is missed), and it preserves order (the WAL records changes in commit order, with transaction boundaries). This 'read the log the database already keeps' approach is what makes CDC low-overhead and correct, versus approaches that add overhead (triggers) or miss changes (polling between polls). Understanding that CDC leverages the WAL — turning the database's own durability mechanism into a change stream — is understanding why it's the right architecture.
And the replication-slot mechanism is what makes CDC reliable — no lost or duplicated changes. A slot tracks the consumer's position in the WAL (the last change it confirmed receiving), and the database retains WAL from that position forward (not discarding it until the consumer has processed it) — so if the consumer disconnects and reconnects, it resumes from its position (no missed changes), and the database knows not to discard WAL the consumer still needs. This gives CDC reliable, resumable, exactly-once-capable delivery (with downstream idempotency) — but introduces the key operational concern: a slow or stopped consumer causes the database to retain WAL indefinitely (it can't discard what the slot hasn't confirmed), which can fill the database's disk (WAL accumulation) — the slot-lag problem that is CDC's main operational hazard. The slot makes CDC reliable, and managing slot lag (ensuring consumers keep up so WAL can be discarded) is the central CDC operational discipline.
The architecture: every piece explained
Top row: the decoding pipeline. The WAL is the database's write-ahead log — the authoritative, ordered record of every change (physical change records the database writes before applying changes, for durability and replication). Logical decoding transforms the WAL's physical records into logical change events — turning low-level page changes into row-level logical changes (this row in this table was inserted with these values, that row was updated from X to Y, this one deleted) — the interpretation that makes the WAL consumable as meaningful changes. A replication slot tracks the consumer's position (the WAL position it has confirmed) and ensures the database retains WAL from there forward — enabling resumable, lossless consumption. An output plugin formats the decoded changes (into a specific format — JSON, protobuf, a Debezium format) for the consumer — the serialization of the change stream.
Middle row: consumption and correctness. Change events are the output: row-level insert/update/delete events with the changed data (and often the before-image for updates/deletes), table and schema info, and transaction context — the meaningful changes downstream systems consume. Debezium and connectors are the tooling: Debezium (the leading CDC platform) connects logical decoding to Kafka (streaming changes to Kafka topics) and other destinations, handling the connection, format, and delivery — the productized CDC layer. Ordering and consistency: changes are delivered in commit order with transaction boundaries (a transaction's changes grouped, so consumers see consistent transactional units — not partial transactions) — the consistency that makes CDC reliable for downstream state. Snapshot plus stream: CDC typically starts with a snapshot (the current state of the tables — the initial full copy, since the WAL only has recent changes) then streams incremental changes (the ongoing WAL-derived changes) — giving downstream the full state (snapshot) plus all subsequent changes (stream), the complete picture.
Bottom rows: applications and comparison. Use cases: replication (keeping a replica or another database current), cache invalidation (invalidating cached data when it changes), search index updates (updating Elasticsearch when data changes), analytics ingestion (feeding a warehouse), and microservice integration (services reacting to each other's data changes) — the broad database-to-downstream synchronization landscape. vs triggers/polling: WAL-based CDC beats triggers (no write-path overhead, no coupling) and polling (no lag, no missed changes, efficient stream) — the architectural superiority of reading the authoritative log. The ops strip: slot lag (the key hazard — a slow consumer causing WAL retention that fills disk; monitoring and managing slot lag), WAL retention (ensuring enough WAL is retained for consumers but not so much it fills disk — the balance the slot manages), and schema evolution (handling table schema changes — CDC must handle schema changes gracefully, propagating them downstream).
End-to-end flow
Trace CDC keeping a search index synchronized with a database. A products database's changes must reflect in an Elasticsearch search index. Setup: a replication slot and Debezium connector on the products table. Debezium first snapshots the table (the current products — the initial full copy into the search index) then streams changes: logical decoding reads the WAL, and each product insert/update/delete becomes a change event (Debezium formats it, streams it to a Kafka topic), which a consumer applies to Elasticsearch (index the new product, update the changed one, delete the removed one). The search index stays current with the database — every committed change flows through the WAL, logical decoding, Kafka, to Elasticsearch, in order, with minimal database overhead (reading the WAL the database already writes). No polling lag, no trigger overhead, no missed changes — the WAL-based CDC keeping the index synchronized correctly and efficiently.
The slot-lag vignette shows CDC's main hazard. The Elasticsearch consumer has a problem (Elasticsearch is down for maintenance, or the consumer is slow), so it stops confirming its position in the WAL. The replication slot, tracking the consumer's position, prevents the database from discarding WAL beyond that position (the consumer might still need it) — so WAL accumulates. If this continues, the accumulating WAL fills the database's disk — a serious problem (the database could run out of space and halt). The monitoring catches it (slot lag growing — the gap between the current WAL position and the slot's confirmed position); the team resolves it (fixing the consumer, or if the slot is abandoned, dropping it so WAL can be discarded). The slot-lag problem is CDC's central operational hazard: a slow/stopped consumer causes unbounded WAL retention, and monitoring and managing slot lag is essential.
The consistency and schema vignettes complete it. A consistency case: a transaction updates multiple products atomically; CDC delivers these changes grouped with the transaction boundary (the consumer sees all the transaction's changes together, not partial), so the search index reflects the transaction consistently — the transaction-boundary preservation that makes CDC reliable for consistent downstream state. A schema-evolution case: the products table gets a new column; CDC must handle this — the change events now include the new column, and the downstream (search index) must accommodate it. Debezium propagates the schema change (schema-change events, updated event structure), and the consumer handles it (adding the field to the index) — schema evolution handled gracefully, a key CDC operational concern (schemas change, and CDC must propagate the changes without breaking). The consolidated discipline the team documents: use WAL-based logical decoding for database-to-downstream synchronization (the correct, low-overhead, complete approach), start with snapshot plus stream (full state plus changes), preserve transaction boundaries for consistency, monitor and manage slot lag (the central hazard — slow consumers causing WAL retention), handle schema evolution gracefully, and use Debezium for the productized CDC layer — because CDC turns the database's own WAL into a reliable change stream, keeping downstream systems synchronized correctly and efficiently, with slot lag as the operational hazard to watch.