Markdown Editor

CDC Pipeline System Design Template

CDC pipeline: log-based capture, watermark chunked snapshot, per-key order, schema evolution, outbox, search, cache and warehouse sinks, replay

Diseño de sistemasCompletadesigncdcpipelinemath

Cómo usar: Use it when replacing dual writes or nightly exports with a change stream from an operational database. Fill the consumer list and the source log retention budget first, because a stalled replication slot that fills the primary's disk is the classic CDC outage. The main pitfall is treating raw table events as a public contract; use an outbox for cross-team events.

Vista previa

System Design: [CDC pipeline name]

Reference design for a change data capture (CDC) pipeline that turns the committed changes of an operational database into an ordered stream of change events, and delivers them to a search index, a cache and a data warehouse. It covers log-based capture, an initial snapshot interleaved with the live log, ordering per key, schema evolution, the transactional outbox pattern, and replay and backfill. Concepts draw on the DBLog watermark approach (Andreakis and Papapanagiotou, arXiv 2010.12597, 2020) and on the concepts documented by Debezium 3.7; the text and the worked design are original. It follows the structure of the System Design Document template. Replace every [bracketed] value and every row marked Example.

Document control

FieldValue
Document ID[SDD-CDC-001]
System / feature[Order database change stream]
Version[0.1]
Status[Draft / In review / Approved / Implemented / Superseded]
Owner[@owner]
Author(s)[@author]
Reviewers[@reviewer-1], [@reviewer-2]
Last updatedYYYY-MM-DD
Classification[Internal; change events contain personal data]
Source databases[Example: PostgreSQL 17 primary orders-db]
RelatedMessage Queue System Design (system-design/design-message-queue), Event Sourcing and CQRS (architecture/event-sourcing-cqrs), Data Pipeline Specification (ai-data/data-pipeline-spec)

Approvals

RoleNameDecisionDate
Tech lead[@name][Approved / Changes requested]YYYY-MM-DD
Database owner / DBA[@name][Decision]YYYY-MM-DD
SRE / operations[@name][Decision]YYYY-MM-DD
Data platform owner[@name][Decision]YYYY-MM-DD
Privacy / security[@name][Decision]YYYY-MM-DD

Revision history

VersionDateAuthorChange summary
0.1YYYY-MM-DD[@name]First draft for design review
0.2YYYY-MM-DD[@name]Example: Replaced lock-and-dump snapshot with watermark-based chunked snapshot
0.3YYYY-MM-DD[@name]Example: Added outbox table for domain events consumed by other teams
1.0YYYY-MM-DD[@name]Example: Approved

Contents

1. Overview

1.1 Problem statement

[Example: The order service writes to PostgreSQL and then, in application code, updates the search index, deletes cache entries and appends to a nightly export for the warehouse. These dual writes are not atomic: when the service crashes between the database commit and the index update, search shows stale orders for days. The nightly export misses rows changed during the export and the warehouse lags by a full day.]

1.2 Proposed solution

[Example: A CDC connector reads the database's write-ahead log through a logical replication slot and publishes one change event per committed row change to a partitioned log, keyed by the table's primary key. Existing rows are captured by a chunked snapshot that runs alongside the live log and is merged with it using low and high watermark markers, so no table locks are needed and the snapshot can pause and resume. Schemas are registered with a compatibility check. Independent consumers update the search index with version-checked upserts, invalidate the cache, and append raw changes to the warehouse, which merges them into tables. Other teams receive domain events through an outbox table captured by the same connector.]

1.3 Decisions requested from reviewers

IDQuestionRecommended optionSection
Q-01Example: How to capture changes?Log-based CDC from the primary's logical replication7.1
Q-02Example: How to capture existing rows?Watermark-based chunked snapshot interleaved with the log7.2
Q-03Example: What ordering do consumers get?Total order per primary key; no order across keys7.3
Q-04Example: Table events or domain events for other teams?Outbox for cross-team contracts; table events inside the owning team7.5
Q-05Example: How much log can the slot retain before we drop it?Cap at 200 GB, alert at 50 GB3.4, 9.1
[Q-nn][Question][Option][Section]

1.4 45-minute interview path

MinutesCoverOutput on the whiteboard
0 to 5Why dual writes fail; which consumers need changes; freshness targetCore requirements FR-01 to FR-05
5 to 10Change rate, event size, log retention, snapshot durationPartitions 16, retention budget, overnight snapshot
10 to 18Capture options and the pipeline diagramSection 6 diagram
18 to 33Deep dive: snapshot interleaved with the log (7.2) and ordering with idempotent consumers (7.3); if the interviewer cares about contracts, use schema evolution and outbox (7.4, 7.5)Watermark sequence, version-checked upsert
33 to 40Failure: connector down, slot growth, replay and backfillFailure-mode table in 9.1
40 to 45Trade-offs and 10xTable in section 10

2. Requirements

2.1 Core functional requirements

IDRequirementPriority
FR-01Example: Emit one event per committed insert, update and delete of the captured tables, with before and after imagesMust
FR-02Example: Capture the full current state of a table on demand (initial load or repair) without locking itMust
FR-03Example: Deliver events for one primary key in commit orderMust
FR-04Example: Keep the search index, cache and warehouse consistent with the database within the freshness targetMust
FR-05Example: Replay changes from a past position and backfill selected keys or tablesMust
FR-06Example: Publish domain events through an outbox in the same transaction as the business changeShould
FR-07Example: Carry transaction ID and commit position on every eventShould
[FR-nn][Requirement][Must / Should / Could]

2.2 Non-functional requirements

IDQualityTargetMeasured as
NFR-01FreshnessExample: p99 below 5 s from commit to event in the logHeartbeat table written every 10 s
NFR-02CompletenessExample: No committed change lost; reconciliation diff zero after convergenceDaily row-count and checksum comparison
NFR-03Source impactExample: Snapshot adds under 10% CPU on the primaryDatabase metrics during snapshot
NFR-04ThroughputExample: 20 000 row changes/s sustainedLoad test
NFR-05RecoverabilityExample: Connector restart resumes without gap within 5 minChaos drill
[NFR-nn][Quality][Target][Measurement]

2.3 Below the line (out of scope)

  • [Example: Multi-master or bidirectional replication between databases]
  • [Example: Cross-key or cross-table transactional delivery to consumers; consumers see per-key order only]
  • [Example: Capturing changes made outside the database log (bulk file loads that bypass it)]
  • [Example: Real-time joins across tables; done by stream jobs (system-design/design-stream-processing-engine)]
  • [Item deferred, with the release that will take it]

3. Capacity estimation

3.1 Assumptions

InputSymbolValueSource
Peak row changes per secondCpC_pExample: 20 000Database statistics x growth
Average row changes per secondCaC_aExample: 6 000Database statistics
Change event size (before + after + metadata, serialised)eeExample: 2 KBSampled events
Log retention for replaytrt_rExample: 7 daysReplay requirement
Log replication factorffExample: 3Log cluster policy
Rows in captured tablesNNExample: 10 billion (4 TB)Table statistics
Snapshot read rate per worker (throttled)rsr_sExample: 50 000 rows/sLoad test against primary
WAL generated at peakggExample: 30 MB/sDatabase metrics

3.2 Throughput and partitions

Bp=Cp×e=20 000×2 KB=40 MB/sB_p = C_p \times e = 20\,000 \times 2\ \text{KB} = 40\ \text{MB/s}

At a target of 5 MB/s per partition, 8 partitions carry the peak; doubling for growth gives 16 partitions per high-volume table topic. Consequence: partition count is set once with headroom, because adding partitions later changes the key-to-partition mapping and breaks per-key ordering across the change. Consumers can scale to 16 instances per topic.

3.3 Log storage

Vday=Ca×86 400×e=6 000×86 400×2 KB≈1.04 TB/dayV_{day} = C_a \times 86\,400 \times e = 6\,000 \times 86\,400 \times 2\ \text{KB} \approx 1.04\ \text{TB/day}
Vretained=Vday×tr×f≈1.04×7×3≈21.8 TBV_{retained} = V_{day} \times t_r \times f \approx 1.04 \times 7 \times 3 \approx 21.8\ \text{TB}

Consequence: 7-day replay costs about 22 TB of log storage; longer history comes from compacted topics (latest value per key) plus the warehouse raw change table, not from longer log retention.

3.4 Source log retention while the connector is down

The replication slot keeps WAL until the connector confirms it:

W1h=g×3 600=30 MB/s×3 600 s=108 GB per hour of outageW_{1h} = g \times 3\,600 = 30\ \text{MB/s} \times 3\,600\ \text{s} = 108\ \text{GB per hour of outage}

Consequence: a connector outage of two hours at peak fills more than 200 GB of the primary's disk. Set max_slot_wal_keep_size (PostgreSQL 13 and later; default -1, unlimited) to a cap the disk can absorb, alert well before it, and keep a runbook for re-snapshot when the cap invalidates the slot.

3.5 Snapshot duration

tsnap=Nk×rs=10104×50 000=50 000 s≈13.9 ht_{snap} = \frac{N}{k \times r_s} = \frac{10^{10}}{4 \times 50\,000} = 50\,000\ \text{s} \approx 13.9\ \text{h}

with k=4k = 4 parallel table workers. Consequence: a full snapshot is an overnight job, so it must be resumable from the last completed chunk, run alongside live streaming, and throttle itself on primary CPU and replica lag.

3.6 Summary

QuantityEstimateDesign consequence
Peak event rate40 MB/s16 partitions per hot topic, fixed up front
Log storage~22 TB for 7 daysCompacted topics and warehouse for longer history
WAL growth when stalled~108 GB/hourSlot size cap, early alert, re-snapshot runbook
Full snapshot~14 h with 4 workersChunked, resumable, throttled, interleaved with log
FreshnessSecondsHeartbeat table to measure it

4. API design

4.1 Change event envelope

Every event has a key (the primary key) and a value envelope. Field names below are this design's own; Debezium documents a similar envelope with before, after, source and op.

{
  "key": {"order_id": 918273},
  "value": {
    "op": "u",
    "before": {"order_id": 918273, "status": "PAID", "total_minor": 125000, "updated_at": "2026-10-22T09:12:03Z"},
    "after":  {"order_id": 918273, "status": "SHIPPED", "total_minor": 125000, "updated_at": "2026-10-22T10:40:51Z"},
    "source": {"db": "orders", "table": "orders", "lsn": "2F/7A3C1B80", "tx_id": 88123401, "commit_ts": "2026-10-22T10:40:51.213Z", "snapshot": false},
    "schema_id": 42
  }
}
opMeaning
cInsert
uUpdate
dDelete (followed by a tombstone with a null value so compaction removes the key)
rRow read by a snapshot chunk

4.2 Control operations

OperationInterfacePurpose
Start snapshotPOST /v1/connectors/{id}/snapshots with tables and optional key filterInitial load, repair or backfill (7.6)
Stop snapshotDELETE /v1/connectors/{id}/snapshots/{sid}Abort a running snapshot
Pause or resumePOST /v1/connectors/{id}:pauseMaintenance windows
StatusGET /v1/connectors/{id}Slot lag, last LSN, snapshot progress
Register schemaSchema registry POST /subjects/{subject}/versionsCompatibility check before publishing

Snapshot requests can also arrive as rows in a signal table inside the source database, which lets the request travel through the log in order with the data (a mechanism Debezium documents for incremental snapshots).

4.3 Consumer contract

  • Events for one key arrive in commit order; events for different keys have no order guarantee.
  • Delivery is at least once: consumers must be idempotent, using source.lsn (or the outbox event ID) as a version or deduplication key.
  • A snapshot r event for a key may arrive after c or u events for the same key only if it reflects a newer or equal state (guaranteed by 7.2).
  • Tombstones mean the key no longer exists.

5. Data model

5.1 Entities

The pipeline's own state is small: offsets, snapshot progress and schemas. The change events themselves live in the log and the stores downstream.

5.2 Storage choices

DataStoreKeyWhy
Change eventsPartitioned log, one topic per tablePrimary keyPer-key order, replay by offset
Connector offsets and snapshot progressSmall replicated store (a compacted topic or the coordination service)connector_id, snapshot_idResume after restart
SchemasSchema registrySubject per topicCompatibility checks
Watermark tableSource database, dedicated schemaSingle row updated with a new UUIDMarkers that appear in the log
Outbox tableSource databaseevent_idSame transaction as business change
Warehouse raw changesAppend-only table partitioned by commit date(table, pk, lsn)Audit and replay beyond log retention

5.3 Access patterns

Access patternServed byPartition key and rationale
All changes for one order in orderTopic orders, partition = hash(order_id)Primary key, so one key's events stay in one partition
Resume streaming after restartOffset store: last_lsn for the connectorOne row per connector; written after the log acknowledges
Resume snapshot after restartChunk table: last completed last_key per tableChunks are ordered by primary key, so a key is a cursor
Apply change to search index only if newerIndex document version = lsn as a numberExternal versioning rejects older writes
Latest state of every key (rebuild a consumer)Compacted topicCompaction keeps the last value per key
Changes for a time range (audit)Warehouse raw table partitioned by commit dateDate pruning

6. High-level design

ComponentResponsibilityScales by
CDC connectorRead the log, run snapshot chunks, publish events, commit offsetsOne active task per source database (log is a single stream); standby for failover
Schema registryStore schemas, enforce compatibilitySmall replicated service
Partitioned logDurable ordered transport, fan-out to consumers (system-design/design-message-queue)Partitions
Search indexerVersion-checked upserts and deletesPartitions per topic
Cache invalidatorDelete cache keys derived from changed rows (system-design/design-distributed-cache)Partitions per topic
Warehouse loaderAppend raw changes, periodic merge into tablesBatch size and merge frequency

7. Detailed design

7.1 Deep dive: how to capture changes

OptionHow it worksStrengthWeakness
A. Dual writes in application codeService writes database, then index, cache and streamNo new infrastructureNot atomic; crashes and races leave systems divergent
B. Query pollingPoll WHERE updated_at > last_seenSimple; works on any databaseMisses deletes, misses rows with equal timestamps, load on the database
C. Triggers into a change tableTrigger writes each change to a table, which is then readCaptures deletes; transactionalExtra write per change inside every transaction
D. Log-based CDCRead the database's own replication logEvery committed change, in commit order, deletes included, little overheadDatabase-specific setup; log retention risk (3.4)

Choice: D. Reason: the log is already the database's source of truth for committed changes, so reading it removes the dual-write gap without adding work to every transaction. Requirements on the source: logical replication enabled, a dedicated slot and publication, primary keys on every captured table, and a replica identity that includes the before image where consumers need it.

7.2 Deep dive: initial snapshot interleaved with the log

The log only holds recent changes, so existing rows need a snapshot, and the snapshot must not overwrite a newer change that the log already delivered.

OptionHow it worksStrengthWeakness
A. Lock and dumpLock tables, dump, record position, unlock, streamSimple consistencyBlocks writes; impossible at 4 TB
B. Consistent export then streamOpen a repeatable-read export at the slot's start position, dump everything, then stream from that positionNo locks; one consistent cutStreaming waits for a 14-hour dump; not resumable; whole tables only
C. Watermark-based chunksPause log processing briefly, write a low watermark, select one chunk by primary key, write a high watermark, resume; drop chunk rows whose keys changed between the watermarks, emit the rest at the high watermarkNo locks; resumable; runs during streaming; selective by table or keyRequires non-stale reads of the chunk and a watermark table

Choice: C for both initial load and repairs. Reason: it keeps log latency within NFR-01 during a 14-hour snapshot, survives restarts by chunk, and the same mechanism serves targeted backfills (7.6).

Why it is safe: any key that changed inside the window is delivered by the log event, which is at least as new as the selected row; any key that did not change inside the window has the same value in the chunk as in the database at the high watermark. The selection must read committed data at least as new as the low watermark write, so run it on the primary (or on a replica only after confirming it has replayed past the low watermark).

7.3 Deep dive: ordering and idempotent delivery

OptionGuaranteeCost
A. Global order (single partition)Total commit orderThroughput of one partition; no consumer parallelism
B. Per-key order (partition by primary key)Commit order per keyNo cross-key or transaction ordering
C. Per-transaction groupingConsumers see whole transactionsBuffering large transactions; complex consumers

Choice: B, with transaction metadata on every event for consumers that need to group. Reason: all three consumers apply changes per key, and per-key order with 16 partitions meets throughput.

Delivery is at least once: after a connector crash it resumes from the last committed offset and republishes some events. Consumers stay correct by version-checking:

  • Search: index with external version = numeric LSN; an older or equal version is rejected, so duplicates and reordering after replay are harmless. Snapshot r events carry the LSN of their chunk's high watermark as the version, so they never overwrite a newer logged change.
  • Cache: always delete (never set) on change; a duplicate delete is harmless.
  • Warehouse: append raw changes; the merge picks the row with the highest (lsn, event order within transaction) per key and ignores duplicates.

Handle primary-key changes as a delete of the old key plus an insert of the new key, so they stay ordered in their own partitions.

7.4 Deep dive: schema evolution

OptionHow it worksRisk
A. Schemaless JSONConsumers parse what arrivesSilent breakage on renamed or retyped columns
B. Registered schemas with compatibility modeEach event references a schema ID; the registry rejects incompatible versionsRequires a registry and discipline
C. Frozen contract per topicOnly explicit versions, new topic per breaking changeSlow to change

Choice: B with backward-compatible mode for table topics and C for outbox contracts. Reason: table schemas change often and mostly additively; cross-team contracts deserve explicit versions. Rules:

  • Adding a nullable column or a column with a default is allowed.
  • Renaming or dropping a column needs a two-step migration: add the new column, backfill, switch consumers, then drop the old one.
  • Changing a column type is a breaking change: new column or new topic.
  • DDL runs through review that checks the registry first; the connector stops on an incompatible change rather than publishing it.

7.5 Outbox pattern for domain events

Table changes describe storage, not business meaning, and expose internal columns to other teams. For cross-team events the service writes an outbox row in the same transaction as the business change; the connector captures the outbox table and routes rows to topics by aggregate type, keyed by aggregate ID, so events for one aggregate keep their order.

ColumnPurpose
event_idUnique ID; consumers deduplicate on it
aggregate_typeRoutes to a topic, for example order
aggregate_idMessage key; keeps per-aggregate order
event_typeFor example OrderShipped
payloadThe versioned contract
created_atDiagnostics; rows deleted after capture or by a retention job

The outbox removes the dual write without a distributed transaction. It does not make consumers exactly-once: they still deduplicate on event_id. See Event Sourcing and CQRS (architecture/event-sourcing-cqrs) when the events themselves become the system of record.

7.6 Replay and backfill

NeedProcedure
New consumer, full historyRead the compacted topic from the start (latest value per key), then follow the live topic
Consumer bug fixed, reprocess 3 daysReset the consumer group offset to a timestamp within log retention; idempotent writes make it safe
Older than retentionReplay from the warehouse raw change table into a replay topic
Downstream store lost or corrupt for some keysStart a snapshot with a key filter; chunks interleave with live changes (7.2)
Slot invalidated by the size capCreate a new slot, start streaming, run a full chunked snapshot; consumers converge by version checks

7.7 How real systems do it

How real systems do it (paraphrased, not copied). Andreakis and Papapanagiotou describe Netflix's DBLog in "DBLog: A Watermark Based Change-Data-Capture Framework" (arXiv 2010.12597, October 2020). The framework reads the transaction log and, to capture full table state, selects rows in primary-key chunks while log processing continues. A dedicated single-row watermark table is updated before and after each chunk select; when the reader sees the matching events in the log, it drops chunk rows whose keys changed between the two markers and emits the remaining rows at the closing marker, so a selected row never overrides a newer logged change. Chunk progress is stored externally so selects can pause and resume, and they can target all tables, one table or specific keys. The paper reports production use across many Netflix services. Debezium 3.7 documents a comparable incremental snapshot driven by a signal table. This template reuses the idea, not the text.

8. Scalability and performance

ConcernApproachLimit before redesign
Log readingOne connector task per database logExample: decoding throughput of one task, around the measured peak x 2
Event volume16 partitions per hot table topicPartition throughput x 16
Large transactionsStream events as decoded; do not buffer whole transactionsMemory if transaction grouping is enabled
SnapshotParallel per table, throttled chunksPrimary CPU budget (NFR-03)
Many databasesOne connector per database, shared log clusterOperational overhead per connector
Consumer lagScale consumers to partition count16 consumers per group

Freshness budget (NFR-01, Example): commit to WAL flush under 10 ms, logical decoding and publish under 1 s, log replication and acknowledgement under 500 ms, leaving more than 3 s of headroom for consumer polling.

9. Reliability, security and operations

9.1 Failure-mode table

ComponentFailureDetectionBlast radiusMitigationRTO
ConnectorCrash or host lossHeartbeat table age; task statusAll consumers stop receiving changes; WAL growsStandby takes over from committed offset; duplicates handled by consumersExample: 5 min
Replication slotExceeds size cap and is invalidatedSlot status in pg_replication_slots; alert on retained WALGap in the change streamNew slot plus full chunked snapshotExample: 14 h to full convergence
Primary failoverNew primary without the slotConnector cannot find slotGap in the streamUse failover-capable slots where the database supports them; otherwise re-snapshotExample: 1 h plus snapshot
Log clusterUnavailablePublish errorsConnector pauses; WAL growsRetry with backoff; cap and alert as for slotLog cluster RTO
Schema changeIncompatible DDLRegistry rejects; connector stopsAll topics of that tableReview gate for DDL; two-step migrationsExample: 30 min
ConsumerBug writes wrong dataReconciliation diffOne downstream storeFix, reset offsets, replay (7.6)Replay time
[Component][Failure][Signal][Scope][Mitigation][Time]

9.2 Security and privacy

ThreatControl
Change events copy personal data to more systemsCapture only listed columns; mask or tokenise sensitive columns in the connector; data map updated per topic
Erasure requestsDeletes flow as events and tombstones; warehouse raw tables follow the erasure procedure; log retention bounded
Replication credentialsDedicated role with replication privilege only; secrets in a vault; rotated
Topic accessPer-topic authorisation per consumer service
[Threat][Control]

9.3 Observability

SignalMetricAlert threshold
FreshnessHeartbeat event age in the logExample: above 30 s for 5 min
Source pressureRetained WAL per slotExample: 50 GB warning, 150 GB critical
SnapshotChunks done, rows/s, primary CPUCPU above budget
ConsumersLag per groupAbove 5 min
CorrectnessRow counts and checksums, database versus each storeAny diff after 1 h convergence

10. Trade-offs and alternatives

DecisionOptionsChosenWhyWhat we give up
CaptureDual writes; polling; triggers; logLog-basedComplete, ordered, low overheadDatabase-specific setup and slot risk
SnapshotLock and dump; consistent export; watermark chunksWatermark chunksNo locks, resumable, selectiveWatermark table; primary reads
OrderingGlobal; per key; per transactionPer keyParallelism with correct per-entity stateNo cross-entity order
ContractTable events; outbox eventsBoth, by audienceInternal speed, external stabilityTwo kinds of topics to govern
DeliveryAt least once; exactly onceAt least once plus idempotent consumersSimple, robustEvery consumer must version-check
At 10x load200 000 changes/s, 400 MB/sSplit the database or capture per shard; more partitions planned from the start; consider decoding on a replica where supportedOne log reader per database becomes the bottleneckMore connectors to run
At 0.1x load2 000 changes/sFewer partitions (2 to 4) per topic; a single shared connector; snapshot time is unchanged because it depends on table size, not change rateSimpler operationsLittle; polling may even be acceptable for non-critical tables

11. Delivery plan and risks

11.1 Milestones

MilestoneScopeExit criterionTarget date
M1Connector, slot, orders topic, warehouse loader in shadowReconciliation diff zero for 7 daysYYYY-MM-DD
M2Chunked snapshot of all captured tablesSnapshot within CPU budget; restart drill passesYYYY-MM-DD
M3Search indexer and cache invalidator; remove dual writesNo stale search results in 14 days of samplingYYYY-MM-DD
M4Outbox for cross-team eventsFirst two consumer teams migratedYYYY-MM-DD

11.2 Rollout and rollback

[Example: Run CDC consumers alongside the existing dual writes, compare outputs, then disable dual writes per consumer behind a flag. Rollback re-enables dual writes; the CDC pipeline keeps running so it can resume.]

11.3 Risks

IDRiskLikelihoodImpactMitigationOwner
R-01Example: Stalled slot fills the primary's diskMediumHighSize cap, alerts, runbook (3.4, 9.1)[@name]
R-02Example: Snapshot load degrades checkout latencyMediumHighThrottle on CPU; off-peak schedule[@name]
R-03Example: Teams consume table topics as a public contractHighMediumTopic access policy; outbox for external teams[@name]
R-04Example: Primary failover loses the slotMediumHighFailover-capable slots or tested re-snapshot[@name]
[R-nn][Risk][L / M / H][L / M / H][Mitigation][@name]

12. Appendices

12.1 Open questions

IDQuestionOwnerDue
OQ-01Example: Can snapshot selects run on a replica with a replay-position check?[@name]YYYY-MM-DD
OQ-02Example: Which columns are masked before leaving the database team?[@name]YYYY-MM-DD
[OQ-nn][Question][@name]YYYY-MM-DD

12.2 Glossary

TermMeaning
CDCChange data capture: producing a stream of committed changes from a database
WALWrite-ahead log, the database's durable record of changes
LSNLog sequence number, a position in the WAL
Replication slotDatabase object that remembers how far a consumer has read and retains WAL until then
Watermark (CDC)A marker row change written to the log to bracket a snapshot chunk; not the stream-processing watermark
TombstoneA null-value message that lets log compaction remove a deleted key
OutboxTable written in the business transaction whose rows are published as events
[Term][Meaning]

12.3 Related templates

  • Message Queue System Design (system-design/design-message-queue): the partitioned log that carries change events.
  • Distributed Cache System Design (system-design/design-distributed-cache): consumer that invalidates on change.
  • Stream Processing Engine System Design (system-design/design-stream-processing-engine): joins and aggregations over change streams.
  • Event Sourcing and CQRS (architecture/event-sourcing-cqrs): when events become the system of record.
  • Data Pipeline Specification (ai-data/data-pipeline-spec): contracts and quality checks for the warehouse load.

12.4 References

ReferenceUse
Andreakis A., Papapanagiotou I., "DBLog: A Watermark Based Change-Data-Capture Framework", arXiv 2010.12597, 2020Watermark-based chunked snapshot (7.2, 7.7)
Debezium documentation 3.7: PostgreSQL connector, incremental snapshots, Outbox Event RouterEvent envelope concepts, signal table, outbox routing
PostgreSQL 18 documentation, replication settings (max_slot_wal_keep_size)Slot retention cap (3.4)
Kleppmann M., Riccomini C., Designing Data-Intensive Applications, 2nd ed., 2026 (inspiration only)Background on CDC and derived data

Standard and licence note

Based on the publicly described DBLog technique and on concepts in the Debezium 3.7 and PostgreSQL 18 documentation cited in 12.4; no standard governs CDC pipelines. This is a reference design to adapt, with illustrative numbers marked Example. Original text written for this collection; sources were used as inspiration only and no text, figures or diagrams were copied. Check the current documentation of your database and connector, because replication settings and connector options change between releases. Template licence: MIT.

Plantillas relacionadas