Skip to content
advanced Phase 18 · Production Capstone and ML Interview Preparation

ML System Design Interviews

Structure ML design answers around data, features, training, and serving.

1h 15m
0 problems
Topic Progress 0%

"'Design a Recommendation System': The First Ten Minutes Decide the Interview"

The prompt appears on the whiteboard: design a system that recommends videos to 200M users. Forty-five minutes, no code. Most candidates open with a model — "I'd use a two-tower neural net with in-batch negatives" — and the interviewer's face closes. The model was never the question. An ML design interview tests whether you can move from a fuzzy business ask to a data source, a label, a training loop, a serving path, and a way to know it still works.

Run the answer in fixed segments, and spend the first segment on questions, not architecture.

Segment What you say or ask What it signals
Problem & decision What action does the score drive? Who acts, how fast? you tie modeling to an owner
Labels Where does the label come from, and how delayed is it? you see feasibility and leakage risk
Data & features Event types, volumes, refresh cadence, join keys your seeds for the estimation math
Model & training loop Retrain cadence, offline split strategy you weigh staleness vs freshness
Serving path QPS, p99 target, sync or async, batch or online you respect hard constraints
Evaluation & monitoring Offline metric, online experiment, drift alarms you cover the full lifecycle
Feedback loops Does the prediction change future labels? the senior-signal answer

A workable 45-minute budget: clarify the problem 4 min, labels and data 8, features 7, model 6, training loop 5, serving 8, evaluation and monitoring 5, risks and interviewer questions 2. If you reach "model choice" before minute 15, you are probably building on unexamined labels.

Concretely, the opening sounds like this: "The score drives which tile a user sees next, so ranking quality is the decision. Labels come from watch time and completes, delayed by up to a day — that delay shapes my retraining cadence. Before I pick a model: do we have logged impressions for every candidate item, or only for shown ones?" That last question alone separates candidates, because it decides whether your training data reflects user preference or the previous ranker's choices.

Two habits earn credit. First, name the prediction problem, the label, and the decision it drives before you name a model — everything downstream is a consequence of those three. Second, quantify one thing early ("200M DAU, say 3B watch events a day") so the interviewer knows you will do the math rather than hand-wave it. The estimation itself comes next; the framework's job is to make its inputs explicit and to leave room at the end for the two answers interviewers probe hardest: monitoring, and what happens when the model's own output poisons its future training data.

End the segment by restating the plan out loud — "I'll estimate storage and QPS, sketch training versus serving, then cover feedback loops and monitoring" — so the interviewer can steer instead of interrupt. A stated agenda turns the session into a conversation you are running.

The agenda is also your recovery plan. When the interviewer cuts across at minute 12 with "what about latency?", you answer from the serving column and return to your place in the plan, instead of losing the thread and restarting the whole design — candidates who never wrote the structure down derail every time the conversation branches, which in a good interview it always does. If the clock runs short, cut model depth and never monitoring: an answer that ends with "here is what I would alarm on, and here is the rollback" still demonstrates lifecycle thinking, while one that dies inside the architecture section reads as unfinished no matter how elegant the two-tower diagram was. The rubric most interviewers carry privately is weighted toward the boring parts — labels, cadence, failure modes — precisely because candidates rehearse the exciting parts.

Back-of-the-Envelope: From 3B Events a Day to Storage, QPS, and a 50 ms Budget

"Roughly how much storage and how many servers?" is where candidates stall. The skill is not arithmetic precision; it is turning a few stated volumes into the quantities that constrain architecture — and saying the scaling law out loud as you go.

Work the standard sequence on these assumptions: 200M daily active users, 3B watch events per day, 100 float features per user profile, 90 days of training history, p99 serving budget of 50 ms.

Request rate. 3B / 86,400 ≈ 35,000 events/s average; assume 3× peak ≈ 100,000 rps. Recommendation retrieval typically runs offline or async per session, but the ranking call in the request path inherits that peak.

Feature storage. 500M profiles × 100 features × 4 bytes = 200 GB raw. A key-value store adds roughly 2× for indexes, replication, and overhead, so plan ~400 GB — shardable across a handful of instances, with attention to hot keys from viral content rather than to raw capacity.

Training data. 90 days × 3B = 27B rows. At ~400 bytes per row (100 features plus label and keys) that is ~11 TB raw; Parquet with columnar compression lands near 2 TB. The standard move is sampling: keep every positive interaction (~1% of rows) plus a 5% negative sample → roughly 1.5B rows, ~600 GB, which trains comfortably and preserves the signal.

Training compute. 1.5B rows through boosted trees takes hours on 16 cores; a deep ranker streaming 5M rows/s across 8 GPUs finishes an epoch in ~5 minutes, so a nightly full retrain with hourly incremental refresh fits any sane window.

Then the serving math, which most affects the design:

Budget item Allocation (p99)
Gateway + auth + routing 3 ms
Feature retrieval (top-500 candidates) 15 ms
Model inference 20 ms
Serialization + response 4 ms
Slack for retries/queueing 8 ms
Total 50 ms

Throughput per replica. Batch-1 inference at 12 ms gives ~83 rps per replica — useless at 100k rps. Batching to 32 requests at 30 ms gives 32 / 0.03 ≈ 1,067 rps, a 12× throughput gain paid for in tail latency. Replicas needed at 70% target utilization: 100,000 / (1,067 × 0.7) ≈ 135 replicas. That fleet size is exactly where Serving Trade-offs: Latency and Cost earns its keep: 135 GPUs versus 135 CPUs, a bigger batch, or a distilled model are different bills for the same traffic, and the latency budget decides which of them is even legal.

A compact script keeps the arithmetic auditable instead of improvisational:

events_per_day, peak_factor = 3_000_000_000, 3
avg_rps = events_per_day / 86_400
peak_rps = avg_rps * peak_factor

profiles, feats, dtype = 500_000_000, 100, 4
raw_gb = profiles * feats * dtype / 1e9

batch, infer_s = 32, 0.03
per_replica = batch / infer_s
replicas = peak_rps / (per_replica * 0.7)
print(f"{peak_rps:,.0f} rps | {raw_gb:.0f} GB raw | {per_replica:,.0f} rps/replica | {replicas:.0f} replicas")

Two probes are worth inviting, because they separate arithmetic from understanding. First: "traffic doubles — which number changes?" Walk the chain again: peak QPS doubles, so replicas double; per-user feature storage does not move, because the profile count per user is unchanged; training data grows only with the number of days you retain. Knowing which quantities scale with which variable is the actual test. Second: "where would you cut first?" — point at the slack line and the batch size: doubling the batch recovers throughput at the price of tail latency, and if the budget can be renegotiated from 50 ms to 70 ms, replicas drop before features do. Candidates who can say which constraint they would spend first sound like people who have owned a bill.

State assumptions, do the multiplication, round hard, move on. The interviewer is checking that your server count scales with the variable that actually grows — QPS, users, or rows — not that you divided correctly three times.

Training-versus-Serving Skew, Point-in-Time Joins, and the Feedback Loop You Must Mention

The demo model scores 0.91 offline and 0.74 in production. Nothing about the architecture diagram explains that gap; the causes live in the seam between the training pipeline and the serving path. Every strong ML design answer names that seam explicitly, because it is where deployed systems quietly fail.

Skew source Concrete example Fix
Two code paths training computes recency in pandas, serving recomputes it in SQL one feature definition shared by both paths
Non-point-in-time joins joining today's balance against last month's label as-of join on event time
Divergent defaults training imputes a median, serving sends 0 identical learned imputation + missing indicator
Mismatched freshness training uses T+1 aggregates, serving uses T+0 match cadence, or train on stale features on purpose
Population drift training on opted-in users only weight or segment; monitor per-slice

The non-point-in-time join deserves its own answer because interviewers probe it directly: if you build training rows by joining "current user state" to historical labels, every feature carries information that did not exist at prediction time, and the model learns shortcuts. The fix is mechanical — join each label to the state as of that moment:

# state must be sorted by event_time; labels are attached to the state that existed then
train_rows = pd.merge_asof(
    labels.sort_values("label_time"),
    state.sort_values("event_time"),
    left_on="label_time", right_on="event_time",
    direction="backward",
)

Then state the invariant in one sentence: the features you train on must be computable at serving time from data that existed at prediction time. A feature store with offline/online consistency is the standard answer to enforce it — the offline table trains the model, the online store serves the identical computation, and the join logic is versioned once.

Feedback loops are the second required close, and the usual example is the ranker itself. Training on logged impressions teaches the model the previous ranker's exposure pattern: high-ranked items collect clicks, low-ranked items never get labels, and the model becomes increasingly confident about an increasingly narrow catalog — position bias hardening into feedback. Mitigations to name: randomize a small exploration bucket, apply propensity weighting to correct logged policies, evaluate counterfactually before promoting, and ship in shadow mode before canary traffic. Where the loop touches sensitive outcomes (lending, moderation), say so — interviewers reward recognizing that feedback can amplify harm, not just error.

Be concrete about the rollout sequence, because it is a standard follow-up: ship the new ranker in shadow mode first — score live traffic, write predictions only to a log, compare against the incumbent on the same requests — then a 1% canary with automatic rollback on guardrail breach, then a 5 → 25 → 100% ramp while the online experiment runs. Each stage answers a different question: shadow tests skew and latency under real inputs, the canary tests blast radius, the ramp tests the metric.

Then close the whole answer with the monitoring loop, completing the lifecycle: input-distribution drift tests against the reference snapshot, prediction-distribution and volume alarms, calibration re-checked once delayed labels arrive, and latency and error budgets held as guardrails — the same discipline covered in Production Monitoring and Drift Detection, here argued as an integral part of the design rather than an afterthought. Monitoring the loop itself deserves three named signals: exposure share per item bucket (is the catalog narrowing?), label coverage for unshown candidates, and score entropy over time. A candidate who can list those three is answering the question nobody else reaches: how would you know your own model is making your data worse? When the interviewer then turns to your capacity estimates, you will be ready for the derivation-heavy follow-ups in ML Interview Question Patterns.

Quiz

1. You have four minutes at the start of an ML design interview. What belongs there?

Question 1 options

2. A ranking service peaks at 100,000 rps. Each replica processes a batch of 32 requests in 30 ms, and you target 70% utilization. How many replicas do you plan?

Question 2 options

3. Your p99 budget is 50 ms and feature retrieval alone measures 35 ms. What is the correct response?

Question 3 options

4. A ranking model trained on logged impressions beats its offline metric but degrades after launch. What is the most likely mechanism?

Question 4 options

Flashcards

Question

What is the fixed segment order for a 45-minute ML system design answer?

Answer

Clarify problem and decision → labels and data → features → model → training loop → serving path → evaluation and monitoring → feedback loops and risks, with a stated agenda up front. Model choice comes only after the label source and serving constraints are known.

Question

Which three quantities does back-of-the-envelope estimation always converge on?

Answer

Storage (profiles × features × bytes, with store overhead), request rate (events per day ÷ 86,400 × peak factor), and per-replica throughput (batch ÷ inference time) — from which replica count follows as peak QPS ÷ (throughput × target utilization).

Question

What is training/serving skew, and what single invariant prevents its worst form?

Answer

Skew is any divergence between the features computed during training and those computed at inference. The invariant: features used in training must be computable at serving time from data that existed at prediction time — enforced with shared feature code, point-in-time joins, and an offline/online feature store with identical logic.

Question

Why does a p99 latency budget constrain the design more than model accuracy does?

Answer

The budget allocates fixed milliseconds across gateway, feature retrieval, inference, and serialization. If retrieval alone consumes most of it, no accuracy gain is reachable — you must precompute features, cache, or change the budget; model-side optimizations and extra replicas cannot recover milliseconds the path never had.

Question

What is a feedback loop in a ranking system, and how do you break it?

Answer

The model's output determines which items get shown, which determines which labels exist, which trains the next model — so exposure concentrates and unshown items stay unlearnable. Break it with a randomized exploration bucket, propensity weighting for the logged policy, counterfactual evaluation, and shadow-mode rollout before real traffic.

Revision Notes

Key Takeaways

  • 1. Model choice is a mid-answer decision; the first ten minutes belong to the decision, the label source, and its delay
  • 2. Estimation is a scaling argument: storage scales with profiles × features, load with QPS, replicas with peak ÷ (throughput × utilization)
  • 3. Batching buys roughly an order of magnitude of throughput and pays in tail latency — state both sides when you use it
  • 4. The label you trained on must be computable at serving time from data that existed at prediction time; point-in-time joins enforce it
  • 5. A feedback loop (exposure → labels → model → exposure) and the monitoring plan are the two closes that separate senior answers from diagrams

Interview Tips

  • • "Design X" with no further detail — open with a one-line agenda and four targeted questions (decision owner, label source and delay, event volume, latency mode); a stated plan makes the interview collaborative
  • • "How many servers?" — do the arithmetic aloud in fixed order (rps, storage, batch throughput, replicas), round hard, and name which variable you would revisit if it doubled; precision is not the score, scaling discipline is
  • • "Where does training/serving skew come from?" — give the five-row table (separate code paths, non-point-in-time joins, divergent defaults, freshness mismatch, population drift) and the invariant sentence; then mention the feature store as enforcement
  • • "How does the model affect its own training data?" — describe position bias hardening into a feedback loop, then list exploration buckets, propensity weighting, counterfactual evaluation, and shadow deployment as the mitigation ladder

Cheat Sheet

ML System Design: Answer Skeleton

Segment Budget Key question
Problem & decision 4 min What action does the score drive?
Labels & data 8 min Source of label? Delay? Volume?
Features 7 min Refresh cadence, join keys
Model 6 min Why this family?
Training loop 5 min Retrain cadence, offline split
Serving 8 min QPS, p99, batch vs online
Eval & monitoring 5 min Offline metric, A/B, drift alarms
Feedback loops 2 min Does prediction change labels?

Estimation chain:

rps        = events/day ÷ 86,400 × peak_factor
storage    = profiles × features × bytes × store_overhead (~2×)
train rows = keep all positives + sampled negatives → Parquet
replicas   = peak_rps ÷ (batch ÷ infer_time × utilization)

Latency budget (p99 = 50 ms): gateway 3 · features 15 · inference 20 · serialization 4 · slack 8.

Skew invariant: features trainable iff computable at serve time from data existing at predict time — shared code, merge_asof on event time, offline/online store parity.

Feedback-loop ladder: exploration bucket → propensity weighting → counterfactual eval → shadow → canary.

Continue Learning