Scenarios
Longer problems, like those in senior system design interviews. A strong answer estimates with numbers first, names the mechanism, then recommends a fix and says what it costs.
1An orders table has 2 billion rows; about 1% change each day, and rebuilding it in the warehouse takes 9 hours. Decide whether to go incremental, and design it.Show the answer
Break-even first
1% of rows change. With a merge penalty of 20×, the crossover is at 5%, so 1% is well inside. An incremental run costs about 1% × 20 = 0.2 of a full run, about 1.8 hours, plus fixed costs that are justified at this scale.
Design
Log-based CDC with before-images; a lock-free incremental snapshot to bootstrap; staged changes deduplicated to one row per key at the highest log position; merge-on-read or rewriting whole partitions, depending on how changes spread across files; and the consumer's position committed together with the state.
Trade-offs and failure modes
The source's log retention is now coupled to the consumer (alert on it, and cap it); partitioning the transport by key breaks transaction atomicity; schema changes need an agreement with the DBA.
Also
A nightly checksum per partition and a monthly full rebuild. Go incremental, but budget for reconciliation from the start.
Read moreThe break-even formulaLog-based CDCBootstrapCommit the cursor with the state
2A CDC reader has been down for 20 hours. The source database's log disk is 85% full and growing 4% an hour. What do you do now, and what do you change afterwards?Show the answer
Estimate
15% of space left at 4% an hour: about 3.75 hours until the disk is full.
Now
Decide between catching up and cutting losses. Restarting the reader works if it can read faster than the source writes; check its throughput. If it cannot catch up within about 3 hours, drop the replication slot to protect the primary, accept that the table must be re-bootstrapped with an incremental snapshot, and tell the DBA. The primary's availability outranks the pipeline.
Afterwards
Alert on the age of the oldest unread log position, cap log retention on the source, write a runbook for re-bootstrapping, and add a health check on the reader.
The principle
The consumer's liveness is the source's availability problem.
Read moreThe claim of zero impact on the sourceBootstrap and represent
3Finance reports that revenue in the warehouse is 0.3% below the source system, yet every job is green. How do you find out why?Show the answer
Localize
Compute a count and a checksum per day on both sides to find which days differ: far cheaper than a full comparison.
Candidate causes
For each differing day: writes that bypassed capture (direct-path loads, TRUNCATE, restores), a consumer position committed before its state when it crashed (loss), polling watermarks skipping long transactions, a schema change that silently dropped a column, or a gap in retention.
Repair and prevent
Repair only the differing ranges. Then reconcile nightly, rebuild fully every month, and require that operations which bypass capture are announced.
Be plain
The pipeline cannot detect this on its own: a missing trace looks exactly like no change.
4Design the replication of an accounts table to a search index and a warehouse, where a transfer must never appear with money missing for more than a few seconds.Show the answer
The constraint
Partitioning the transport by key splits a transfer's two rows across partitions.
Options
- Partition by transaction: keeps a transfer together, but serializes each transaction and can lose per-account order when two transfers touch one account in different partitions.
- Buffer each transaction at the sink and commit it atomically: latency grows with the largest transaction and memory is unbounded for a huge one, so cap transaction size and route oversized ones to a slow path.
- Accept intermediate states, but publish a marker "consistent up to position P", the lowest position across all partitions, and have dashboards read only up to P.
Recommend
Option 3 with a short delay, since a few seconds is the stated tolerance; option 2 only for the one report that needs a strict balance.
Failure mode
One stalled partition holds P back for everyone, so alert on the spread between partitions.
5The product team wants a type-2 history table of customers and a view of the maximum order value per city, both updated within a minute. How do you build them?Show the answer
History table
It needs before-images, order per key and an atomic close-and-insert, so log-based CDC with partitions ordered by key; polling cannot do it.
Maximum per city
MAX has no inverse. Options: rescan a city when its maximum is deleted (linear in the city's rows; fine if cities are small or deletes rare); keep every value, or the top K, per city (storage proportional to input, or to K × cities); or recompute each minute only the cities that were touched. With about 500 cities and rescans of the hot ones, this is cheap.
Freshness
Each commit has a fixed cost, so choose a cadence, say 20–30 seconds, where the overhead stays small; "within a minute" is a floor to meet, not a free setting.
Recommend
Capture once, feed both, and reconcile nightly.
Read moreFeeding history tablesAggregation: the load-bearing distinction
6A service writes to the database and then publishes to Kafka, and about 1 in 2,000 events never arrives. A teammate proposes retrying the publish. Is that enough?Show the answer
Diagnose
A dual write has a crash window between its two writes, and retrying inside the same process does not help if the process dies in that window. The loss rate is the failure rate times the window, on every write.
Options
- Retry plus periodic reconciliation, which hides the problem without removing it.
- A transactional outbox: write the event in the same transaction as the business row, and publish from the outbox with a tailing process or CDC.
- CDC directly from the business tables.
Trade-offs
The outbox adds one write per event and needs old rows cleaned up, and delivery is at least once, so consumers must be idempotent, using the event ID.
Recommend
The outbox: it gives an explicit, controlled event schema rather than one borrowed from the tables.
7A bug corrupted a derived table 50 days ago. The CDC topic keeps only 14 days of changes. Plan the repair.Show the answer
The constraint
You can replay only as far back as retention: 14 days.
Plan
Rebuild the older 36 days, and in practice the whole range, by full recomputation from the source table or archived snapshots. Build into a shadow table; start the live pipeline earlier than the backfill's end so the seam overlaps deliberately; use an idempotent, keyed upsert sink; run old and new in parallel and compare until there are no differences; then swap by pointer. Throttle the backfill so it does not starve the live pipeline or the source.
Afterwards
Raise retention to cover the longest repair you are willing to do, or archive the topic to cheap storage, accepting a cost that grows with time kept.
Read moreReplay is a retention choiceBackfill and cutoverBlue-green at table level
8Management asks why every pipeline cannot simply be made incremental to save compute. Answer.Show the answer
The arithmetic
Incremental cost = changed fraction × size × cost per changed row + fixed cost. For small tables the fixed cost dominates: a 2-minute rebuild cannot be beaten by a system that needs infrastructure and an on-call rota. For tables with high churn, the changed fraction is above the crossover: 20% daily change with a 20× penalty costs 4 times the rebuild.
The kind of risk
A rebuild corrects itself every night. An incremental pipeline is a running total over all history, correct only if nothing was ever lost, duplicated or reordered, and it fails silently.
Recommend
Decide per table: large tables with low churn go incremental, with reconciliation; append-only partitioned data uses simple watermarks; everything else is rebuilt.
Read moreThe break-even formulaWhat change data capture forbidsWatermark-based incremental batch
9Your warehouse must mirror a PostgreSQL OLTP database. Choose a change data capture (CDC) approach and describe its failure modes.Show the answer
Choose
Log-based CDC, reading the database's write-ahead log: it is complete (deletes, every intermediate state, commit order) and cheap for the source. Query-based polling is acceptable only if you consume full-state upserts and can tolerate missing deletes.
Risk: the slot
The replication slot keeps write-ahead log on disk while the consumer is down. Set max_slot_wal_keep_size, monitor slot lag, and decide whether you would rather lose the slot (and take a new snapshot) than the database.
Initial load
The first full copy needs chunked snapshotting with watermarks (record a low watermark, read a chunk, record a high watermark, and drop snapshot rows whose key changed between the two), so that it has no gaps and no ordering errors.
Schema changes
They arrive as events, so define the policy in advance: fail, evolve, or quarantine.
Read moreLog-based CDC: the claim of zero impactPolling and the completeness gapBootstrap: the lock-free way