Skip to content
About
Main content

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.

Try each one before you open the answer.
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 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 that are justified at this scale.

Design

Log-based with ; a lock-free to bootstrap; staged changes deduplicated to one row per key at the highest log position; or rewriting whole , 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 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.

Read moreEvery method has a bypass setDerived state drifts

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

  1. 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.
  2. Buffer each transaction at the sink and 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.
  3. 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.

Read moreOrdering and transactional groupingThe escapes

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; 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

  1. Retry plus periodic reconciliation, which hides the problem without removing it.
  2. A transactional : write the event in the same transaction as the business row, and publish from the outbox with a tailing process or CDC.
  3. 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 , using the event ID.

Recommend

The outbox: it gives an explicit, controlled event schema rather than one borrowed from the tables.

Read moreWhy dual writes failOne source of truth

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 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 . Build into a ; start the live pipeline earlier than the 's end so the seam overlaps deliberately; use an idempotent, keyed 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 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

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 : 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