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.
1Design the storage for an event table of 2 billion rows and 25 columns (about 200 bytes per row) with two access patterns: looking up one parcel's events, and a weekly aggregate over 2 columns.Show the answer

Estimate

2 × 10⁹ rows × 200 B = 400 GB. The aggregate needs 2 of 25 , so a columnar layout reads about 8% of the bytes before , and less after.

The aggregate

(a layout) in with 128 : about 640,000 rows each, about 3,125 files. Object storage's smallest efficient read is above 1 MB, which these units clear.

The lookup

It needs the whole entity. In pure columnar form that is 25 separate reads, each paying , so keep a row-store or key-value copy keyed by parcel.

Cost

Double storage, more at ingestion, and a between the two copies.

Read moreFour numbers per layoutPAX (hybrid) layoutWhat the layouts forbid

2A nightly job must apply 5,000 scattered corrections and honour deletion requests on a lake table stored as 128 MB files. Choose a strategy.Show the answer

Rule out copy-on-write

Its cost per change is the unit size divided by the change size, U / d ≈ 640,000×. The corrections touch about 2,500 distinct files, so roughly 320 GB would be rewritten for 1 MB of change.

Choose

for the corrections, and vectors for the deletions: files are immutable and the writer can look up positions. A raw bitmap is about 80 per file, smaller with Roaring compression.

Operate

Derive the from measured costs (), and rewrite in the same transaction as . If the table is reclustered often, become the better fit, since positions keep changing.

Failure modes

Deltas accumulating without bound, and positions broken by rows that moved.

Read moreCopy-on-writeMerge-on-readDelete vectorsThe compaction interval

3Reports on a merge-on-read table get slower week after week, while traffic stays flat. Diagnose.Show the answer

Hypotheses

  • Deltas accumulating with no compaction schedule: read cost grows with their number.
  • building up.
  • A few hot files with huge numbers of deltas, hidden by a normal-looking average.

Measure

Deltas per file, as a distribution rather than a mean.

Fix

Compute the right compaction interval, and compact the hot files first.

Trade-off

Compaction costs write .

Read moreMerge-on-readCompaction policy

4Your team stores JSON events in a document column. After a client release renamed some keys, queries became slow. What happened, and how do you fix it?Show the answer

Diagnose

The engine shreds JSON into hidden typed columns based on the schema it infers. That works only while the schema holds: renamed keys create new sparse columns, and skipping stops working, silently.

Fix

Shred the stable keys into explicit typed columns, validate schemas at ingestion, alert on the rate of new keys, and keep the raw JSON as a fallback. When flattening nested data, keep path information ().

Read moreDocument layoutShredding

5Pick a compaction policy for a write-heavy time-series store holding 1 TB, with a 1 GB in-memory buffer and a size ratio of 10 between levels.Show the answer

Estimate

L = log₁₀(1,000) = 3 levels. : write amplification about T·L = 30, reads touching about 3 runs, space about 1.1×. Tiered: writes about 3, reads touching about 30 runs, space up to 10×.

Choose

Heavy writes and mostly recent reads point to tiered or time-windowed compaction, with to cut the read cost.

Caveat

These formulas are asymptotic models; measure on your workload.

Read moreCompaction policy

6A 4 TB event table in object storage is queried by customer_id (point lookups returning 10–100 rows) and by event_date (ranges of 1–7 days, over two years of data). Design the physical organization.Show the answer

Estimate

4 TB in 128 MB files is about 31,000 files. One day out of two years selects 1/730 of the data, so a date-sorted table opens about 31,000 ÷ 730 ≈ 43 files instead of 31,000. A customer lookup selects about 10⁻⁸ of the rows: one file if sorted by customer, all of them if not.

Choose

Two dimensions with different shapes. Do not Z-order if one of them carries 80% of the scanned bytes. Sort by event_date (730 distinct values, fewer than the number of files), and serve customer lookups with a Bloom filter (about 10 bits per row; on 10¹⁰ rows, check its size) or with a separate key-value copy, since a query has a planning floor of about 200 ms and cannot serve fast point lookups.

Cost

A second copy (storage, write amplification, a freshness gap) and the ongoing rent of reclustering.

Failure mode

Late-arriving data breaks the date order, so monitor .

Read moreClustering payoffOne order per copy of the dataWhen should you use Z-order?

7A query that was fast for six months now scans the whole table. Nothing in the code changed. Diagnose it.Show the answer

Hypothesis

The data's sortedness decayed: a backfill, a new source writing in a different order, a compaction that dropped the order, or a skewed hot key.

Measure

For the filtered column: the overlap of [min, max] ranges across files, the clustering depth, and the ratio of files read to files with matching rows. If every file's range overlaps, is the cause. Also look for one file with a sentinel outlier.

Fix

Recluster only the affected files (each costs a full rewrite of its unit; budget it as rent), write backfills sorted, and put clustering depth on the dashboard.

Why it was silent

Averages look fine until the overlap crosses a threshold, and then every query falls off the cliff at once.

Read moreFewer units, not less waste per unitMeasuring clustering qualityThree properties of zone maps

8Should you Z-order a table of a million files that is filtered on four columns?Show the answer

The floor

With d = 4 dimensions, any single-column query reads at least ≈ 31,600 files, 3% of the table.

Decide

If one column carries 80% or more of the scanned bytes, sort by that column alone: Z-order would give up a factor of U on the dimension that matters to buy a factor of about 32 (U^(1/4)) on each of the others. If the four columns are used about equally, Z-order wins by turning a full scan into a 3% scan for every query.

Check

Correlation between the columns (correlated columns waste bits but lower the floor), value ranges (bucket by quantiles first), and the write rate (reclustering rent). With five or more dimensions, consider secondary structures instead.

Read moreZ-order and space-filling curvesWhen should you use Z-order?

9A nightly join of two 2 TB tables takes 6 hours, and one task dominates the run time. Should you bucket the tables?Show the answer

Diagnose

One long task suggests key skew. concentrates skew: every row of a hot key lands in one bucket that cannot be split, so on its own it would not help. Check the key histogram first.

Options

If skew is mild, bucketing both tables on the join key, with the same count and hash, removes a shuffle of about 4 TB. But it fixes both layouts permanently, and every writer must follow it. If a few keys are hot, handle them separately (salt them, or broadcast the small side), then consider bucketing for the rest.

Trade-off

The cost moves to write time, where it is paid on every write.

Read moreBucketingSkew is worse than expected

10A service on NVMe reads 4 KB blocks and reaches 60 MB/s on a drive rated for 7 GB/s. Management wants a faster drive. What do you do?Show the answer

Estimate

One request in flight at 80 µs gives about 50 MB/s, which matches what you see, so a faster drive will not help. Filling the drive needs 7 GB/s × 80 µs ÷ 4 KB ≈ 140 requests in flight ().

Check

Whether the reader is synchronous or uses mmap ( are one request at a time); then move to asynchronous I/O (io_uring) or enough threads. Also check alignment, since misaligned 4 KB reads can cost up to 4×, and whether kernel copies and system calls, about 1 µs per I/O, have become the fixed cost.

Trade-off

With explicit I/O you own caching and eviction.

Read moreMemory mappingPrefetchingAlignment

11Design the read path for a weekly report that must scan 12 GB from object storage in under 10 seconds.Show the answer

Estimate

The target is 1.2 GB/s. One connection streams about 80 MB/s, and an 8 MB request takes about 50 ms of latency + 100 ms of transfer = 150 ms, so one connection delivers about 53 MB/s. That needs about 23 requests in flight (1,200 ÷ 53); with margin, 32–64.

Design

Requests of 8 MB or more (for latency to be only 10% of each request, about 36 MB). Use column pruning and row-group skipping to read fewer bytes in the first place.

Costs

Request fees (12 GB ÷ 8 MB = 1,500 requests, small) and buffer memory (64 × 8 MB = 512 MB).

Failure modes

Per-prefix rate limits (503 errors) and stragglers: hedge the slowest requests.

Read moreThe three numbersPrefetching