End-to-End ML System Design Questions
Designing a complete machine learning system from problem to production. Covers the components and architecture of a production ML system, data flow from ingestion to serving, scalability, and integration of models into a larger product. Emphasizes the whole-system design tradeoffs that appear in ML system-design interviews.
What would you want on the monitoring dashboard for a model that's been live in production for a while? Be specific about what would go on it, and how you'd explain to a non-technical executive why one of those panels just turned red.
Sample Answer
Direct answer
A production model's dashboard needs three tiers of panels: system health (is it up and fast), input and prediction health (is what is arriving, and what the model is outputting, still what is expected), and outcome health (is it still right), because a model can look perfectly healthy on the first tier while being silently wrong on the third. When a panel turns red for a non-technical executive, the useful explanation skips the underlying statistic entirely and leads with the business consequence in one sentence, offers the mechanism only as a short "why" if it is known, and closes with what is already being done about it, because the executive's real question underneath "why is it red" is almost always "should I be worried, and is someone already on it."
Structured elaboration
| Panel | What it tracks | Tier | Example alert condition |
|---|---|---|---|
| Traffic and latency | Request volume, p50/p95/p99 (50th/95th/99th percentile) latency, error rate | System | p99 latency above target for 5 minutes |
| Input and feature health | Per-feature distribution shift, missing-value rate, schema violations | Input | A feature's distribution shift crosses a set threshold |
| Prediction distribution | Whether predicted classes or scores are shifting over time | Input | Predicted-positive rate moves sharply from its recent baseline |
| Outcome or quality proxy | Accuracy against delayed ground truth, or a fast proxy such as override or manual-review rate | Outcome | Proxy metric degrades beyond a set band |
| Business impact | The KPI (key performance indicator) the model exists to move, for example approval rate or conversion | Outcome | KPI moves beyond an agreed tolerance |
| Deploy markers | Every rollout overlaid as a vertical marker on every other panel | Correlation aid | N/A, always visible |
Explaining a red panel to a non-technical executive, a repeatable structure:
- Impact first, stated in business units, not model units: "we are likely approving more risky applications than intended," not "PSI (population stability index) crossed a threshold."
- One-line mechanism, in plain language, only if it is actually known: "the upstream sign-up form changed and is sending empty fields," or, if not yet known, "we are actively narrowing it down between a data problem and a real change in customer behavior."
- What is already being done and by when: "we have routed higher-risk cases to manual review while we confirm the cause; next update in two hours."
Applied variant, training-job health metrics: the same three-tier structure applies to the training pipeline itself, not only the serving path: a training-job dashboard needs its own system tier (job success rate, time-to-completion), its own input tier (dataset freshness, row-count anomalies at ingestion), and its own outcome tier (offline validation metrics on the freshly trained candidate before it is ever promoted), because a training pipeline that "succeeds" every run but silently trains on stale or malformed data is the training-side equivalent of a model that is fast and up but wrong.
Worked example
Suppose the outcome panel for a fraud model shows its fraud-catch rate has fallen to roughly half its usual level over the last two days, based on confirmed-fraud labels that just arrived. Framed for the model's own dashboard, an engineer would say "our recall on confirmed fraud has dropped sharply over the last 48 hours." Framed for the executive, the metric name disappears entirely: "in the last two days we caught roughly half as much fraud as usual before it went through; we do not yet know if this is a bug or a new fraud pattern, and we have temporarily tightened manual review on borderline cases while we find out."
Trade-offs and pitfalls
A common wrong turn is building only the system tier, because it is the easiest to instrument, which gives false confidence that "monitoring is in place" while the model can be silently wrong for days; this is exactly the failure mode behind a model whose quality quietly drops with nobody noticing. Translating a red panel for an executive by walking through the metric's definition reads as evasive at precisely the moment the executive wants a fast, confident answer. Omitting deploy markers from the outcome and quality panels is the single fastest way to rule out "did we just ship something" as the cause, and skipping it means every incident starts from scratch.
A product wants an AI assistant, built on retrieval and an LLM, that drafts content and takes actions inside a workflow. Where does a human need to be in the loop before its output actually reaches a customer or goes live?
Sample Answer
Direct answer
A human needs to be in the loop at the point where the assistant's output is both hard to fully verify automatically and has real-world consequence if wrong: specifically, before any output reaches a customer or triggers an action outside the system, unless an automated risk score is confidently low. The design decision isn't "always require a human" (that doesn't scale) or "never require one" (that's how a bad draft or a wrong action ships); it's a risk-scored router that sends the low-risk majority straight through and the flagged minority to a reviewer.
Structured elaboration
Architecture
flowchart TD
A[User or workflow trigger] --> B[Retrieval: grounding documents]
B --> C[LLM drafts content or action]
C --> D[Automated safety and policy classifiers]
D --> E{Risk score}
E -->|Low risk| F[Auto-publish or execute]
E -->|High risk| G[Human review queue]
G --> H{Reviewer decision}
H -->|Approve| F
H -->|Edit needed| C
H -->|Reject| I[Discard and log]
F --> J[Audit log: version, risk score, reviewer]
Key design decisions and why
- Retrieval grounds the draft before the LLM ever generates. Pulling relevant, authoritative source documents into the prompt reduces hallucination and gives the output something to be checked against, both by the automated classifiers and by a human reviewer, rather than a reviewer having to fact-check from scratch.
- A risk score, not a binary rule, decides whether a human sees it. The safety/policy classifier stage scores each draft or proposed action on dimensions like policy-sensitive content, factual claims that are hard to verify automatically, and irreversibility of the action (a drafted email is reversible before sending; a completed refund or a live-published page is not). This is the design decision that makes human review scale: it's not "review everything" or "review nothing," it's "review the fraction that's actually risky."
- Irreversibility is the single strongest trigger for mandatory human review, independent of how confident the risk classifier is otherwise. An action that can't be undone once taken (sending a customer communication, executing a payment, publishing externally) should route to a human by default even when the content looks fine, because the cost of being wrong is asymmetric: a bad automated classification on a reversible draft costs an edit; on an irreversible action it costs an incident.
- The reviewer's decision feeds back into the loop, not just forward. An "edit needed" outcome sends the draft back through generation (with the reviewer's correction as added context), not just a one-off manual fix; this is what keeps human review from becoming a dead-end patch that never improves the underlying system.
- Every decision, automated or human, is logged with the model version and risk score. This is what makes "who approved this and why" answerable after the fact, which matters both for a customer complaint and for tuning the risk classifier's threshold over time based on which auto-approved outputs later turned out to be problems.
Worked example
Sizing the human-review queue is a straightforward capacity calculation once you know the flag rate and reviewer throughput. Suppose the assistant generates 100,000 drafts/actions per day, and the risk classifier flags the top 5% as high-risk:
Flagged/day=100,000×0.05=5,000If each reviewer can process 200 items/hour over an 8-hour shift:
Reviewer capacity/day=200/hr×8hr=1,600 Reviewers needed=⌈5,000/1,600⌉=4Four reviewers clear the daily flagged queue with same-day turnaround. This number is what turns "human in the loop" from an abstract safety principle into an actual staffing and SLA (service-level agreement) commitment: if the flag rate crept up to 15% instead of 5%, the same math needs 10 reviewers, not 4, which is exactly the kind of capacity conversation this design should force before launch, not after the queue backs up and outputs start sitting un-reviewed for days.
Trade-offs & pitfalls
- Setting the risk threshold too conservative (flagging too much) doesn't make the system safer in practice, it makes the human queue the bottleneck, and a backed-up queue creates pressure to rubber-stamp reviews quickly, which defeats the purpose; the threshold has to be tuned against real reviewer capacity, not set to the most cautious number in isolation.
- Routing purely on content risk while ignoring reversibility is a common miscalibration: a mundane-sounding draft that triggers an irreversible action (an automated refund, a message to a large distribution list) deserves review even if the classifier sees nothing alarming in the text itself.
- Treating human review as a one-way gate rather than feeding "edit needed" corrections back into generation wastes the signal reviewers are generating; over time that signal should also inform retraining or prompt refinement, not just fix one instance.
- A retrieval layer reduces hallucination but doesn't eliminate it, and it's a mistake to treat "grounded in retrieved documents" as equivalent to "verified"; the retrieved documents themselves can be stale or wrong, so the safety pipeline still needs to check the draft's claims, not just confirm it cited something.
- Audit logging is easy to under-scope to just the final output; capturing the risk score, the model version, and the specific reviewer decision (not just "approved") is what makes it possible to later diagnose whether a bad outcome was a classifier miss, a reviewer miss, or a genuinely hard edge case, and those have different fixes.
During a long distributed training run, one worker intermittently falls behind and the whole job slows down. The model, code, and data have not changed. What would you inspect first, and what mitigation would you try to keep the run moving?
Sample Answer
What I would inspect first
I would start with per-step timing on the slow worker versus the rest of the cluster. If the code, model, and data are unchanged, a single lagging worker is usually a host or systems issue, not an ML issue.
Checks in order
- GPU utilization and memory bandwidth on the slow node
- Data loader wait time and local disk throughput
- CPU steal, thermal throttling, and noisy neighbors
- Network errors, packet drops, and collective communication logs
- Kernel and container logs for retries or hardware faults
Mitigation
If the worker is clearly abnormal, I would cordon it, move the job to a fresh node, and keep the training moving. If the slowdown comes from input starvation, I would reduce preprocessing on that host, increase local caching, or lower dataloader contention.
Worked example
If most workers take 180 ms per step but one takes 420 ms and spends 250 ms waiting on input, the bottleneck is the input path, not the model.
The goal is to isolate the bad actor quickly and avoid letting one slow node stall the whole synchronous job.
A prototype that performed well in small-scale testing now needs to serve millions of users. Walk through how you would scale it up, and what you'd prioritize to avoid an embarrassing amount of downtime along the way.
Sample Answer
Direct answer
Priority order, not a shopping list: first decouple stateless request-serving from anything stateful (sessions, in-memory caches) so you can add replicas freely, second put an autoscaler in front of that stateless tier driven by a real load signal (queue depth or p95 latency, not just CPU), and third roll the whole thing out with staged traffic shifts (a canary) gated on service-level objectives (SLOs, the target thresholds for latency/availability you commit to) so a bad change is caught on 1% of traffic instead of 100%. Everything else (caching, async processing, monitoring) supports that spine.
Structured elaboration
1. Define the targets before touching infrastructure. Pin down p95/p99 latency (the 95th/99th percentile response time), an availability target (e.g. 99.9%), and a rough cost ceiling. Without these, "scale it up" has no stopping point and no way to know if a change helped.
2. Split the compute architecture into two paths.
- Synchronous, low-latency path: stateless model-serving replicas behind a load balancer, autoscaled on request-driven metrics (queue depth, in-flight requests, or p95 latency) rather than CPU alone, since CPU can look idle while requests queue on I/O.
- Asynchronous/batch path: anything that doesn't need an immediate response (bulk scoring, precomputation) goes through a durable queue consumed by an autoscaled worker pool, so a traffic spike on the async side doesn't compete with the latency-sensitive path for the same replicas.
3. Externalize state. Move sessions, feature lookups, and any per-request context out of the model-server process into a shared cache or store. This is what actually enables horizontal scaling: if state lives in the replica's memory, you can't add a second replica without splitting user traffic by session, which reintroduces the bottleneck you're trying to remove.
4. Add a caching layer for repeat/hot queries in front of the model-serving tier, sized to the fraction of traffic that's actually repeat, not universally, since caching stale predictions for a fast-moving model can itself be a correctness bug.
5. Observability before scale, not after. Golden signals (latency, traffic, errors, saturation) with alerting tied to the SLOs from step 1, so a slow rollout is visible before users report it.
6. Progressive rollout. Canary 1% of traffic, gated on automated SLO checks, then 5%, 25%, 100%, each stage paused until the previous stage's metrics are clean. Keep a one-click rollback path at every stage; this is what actually prevents "an embarrassing amount of downtime," not the capacity math itself.
Worked example
Say the prototype was validated at low volume, and the target is 2,000,000 daily active users, each issuing an average of 5 requests/day (a planning assumption, stated explicitly so the arithmetic is reproducible).
avg requests/day=2,000,000×5=10,000,000Convert to average queries per second (QPS, requests handled per second):
avg QPS=86,40010,000,000≈115.7Traffic isn't flat across the day; assume a peak-to-average factor of 3x (a common planning multiplier for consumer traffic, stated as an assumption here):
peak QPS≈115.7×3≈347Now assume load testing on a single replica measured a sustainable capacity of 20 QPS at the target p95 latency (this is the kind of number you'd get from your own load test, not a vendor benchmark, and it's the pinned input driving the rest of the math):
replicas needed=20347≈17.4→18 replicasAdd headroom for one replica's worth of failover (N+1) plus a burst buffer, say 30%:
18×1.3≈23.4→24 replicasSo the autoscaler's target ceiling for the synchronous serving tier is roughly 24 replicas at this projected peak, with the floor set by off-peak QPS using the same per-replica capacity figure. The point of doing this arithmetic explicitly is that it's re-runnable the moment your real load test gives you a different per-replica capacity number or your usage assumptions change.
Trade-offs & pitfalls
Over-provisioning for a peak factor you guessed wrong wastes real money every hour of every day; under-provisioning turns "millions of users" into an incident. Prefer measuring your actual peak-to-average ratio from prototype traffic over guessing, and re-derive the replica count once you have it. Stateful services (sticky sessions, in-memory model caches keyed by user) quietly block horizontal scaling even after you've "added autoscaling," so audit for hidden state before trusting the replica math. A canary only protects you if the signal it watches is fast and sensitive enough: SLO checks based on hourly aggregates won't catch a regression that matters within minutes. Finally, resist scaling complexity ahead of evidence: building a five-region, multi-tier architecture for a prototype that hasn't proven its growth curve yet is itself a way to introduce downtime, just earlier.
graph LR
A[Client request] --> B[Load balancer]
B --> C[Stateless model-serving replicas]
C --> D[Shared cache / session store]
B --> E[Async queue]
E --> F[Autoscaled worker pool]
C --> G[Monitoring: SLO dashboards]
G --> H[Canary gate]
H --> I[Traffic ramp: 1% to 100%]
You're building the evaluation and rollout plan for a model used in a healthcare triage setting, where a wrong prediction has real consequences. What would that evaluation plan need to cover before you'd be comfortable putting the model in front of a clinician?
Sample Answer
Direct answer
The evaluation plan needs three layers before a clinician ever sees a prediction: rigorous offline validation on data that looks like the deployment population, a period where the model runs silently alongside clinicians so you measure real-world performance without it influencing care, and a staged, monitored rollout with pre-agreed stopping rules. The single organizing principle: in triage, a false negative (missed urgent case) and a false positive (unnecessary alarm) have very different costs, so the plan has to be built around that asymmetry rather than around a single aggregate accuracy number.
Structured elaboration
Evaluation-to-rollout pipeline
flowchart TD
A[Offline evaluation on multi-site holdout] --> B[Silent shadow deployment]
B --> C{Safety and fairness gates}
C -->|Fail| D[Return to model or data team]
C -->|Pass| E[Staged pilot: single site, assistive mode]
E --> F[Prospective RCT or stepped-wedge trial]
F --> G{Non-inferiority and safety met}
G -->|No| D
G -->|Yes| H[Full clinical rollout]
H --> I[Continuous drift and subgroup monitoring]
I --> J[Periodic re-validation]
J --> C
1. Offline evaluation, before anything touches a clinician
- Hold out data by time and by site (not a random split), so the estimate reflects performance on a hospital or population the model has not seen, catching cases where the model quietly learned a site-specific artifact instead of the clinical signal.
- Report sensitivity (recall) on the urgent-case class as the headline metric, not overall accuracy, because urgent cases are usually a small fraction of volume and accuracy can look excellent while missing most of them.
- Report calibration (does a predicted probability of 0.8 correspond to roughly 80% of those cases actually being urgent) separately from discrimination, because a clinician needs to trust the number, not just the ranking.
- Break every metric out by demographic subgroup (age, sex, site, language) rather than reporting one pooled number, since a pooled metric can hide a subgroup where the model is unsafe.
2. Silent (shadow) deployment
The model runs on live cases in real time, its predictions are logged, but clinicians never see them and never act on them. This is the step that catches "worked in offline eval, breaks in production" failures: label leakage in the historical data, a preprocessing mismatch between the training pipeline and the live feature pipeline, or a shift in the patient population since the training data was collected. Compare shadow-period sensitivity and calibration against the offline estimate before proceeding.
3. Staged, human-in-the-loop clinical validation
- Assistive mode first: the model's output (score plus a plain-language rationale) is shown to the clinician, who retains the decision; nothing is automated.
- A single site or unit before a multi-site rollout, so you learn how clinicians actually use the tool (do they defer to it, ignore it, use it only for edge cases) before that behavior is baked in everywhere.
- A prospective trial (randomized or stepped-wedge) with endpoints defined ahead of time: time-to-treatment for urgent cases, rate of missed critical events, and a pre-specified non-inferiority margin, so "did it help" is answered by a design that was agreed on before you saw the data, not by a post-hoc read of favorable-looking numbers.
- Stopping rules for harm: if the missed-urgent-case rate crosses a pre-agreed threshold during the trial, the trial halts. This has to be decided before the trial starts, not negotiated after a bad week.
4. Governance and monitoring that outlives the launch
- A model card and data sheet documenting training population, known limitations, and intended use, reviewed by a model risk or clinical safety committee before go-live.
- Post-deployment: real-time dashboards for sensitivity/FNR (false negative rate, the fraction of true urgent cases the model misses) by subgroup, calibration drift, and feature drift, with automatic alerts and a rollback path if any breach the pre-agreed threshold.
- A retraining and re-validation cadence: the plan doesn't end at launch, it specifies how often the model gets re-evaluated against fresh holdout data as the patient population and clinical practice shift.
Worked example
Say the target patient population has an urgent-case prevalence of 3%, and the triage system processes 5,000 cases a day.
Expected urgent cases/day=5000×0.03=150At a false-negative rate (FNR, the fraction of true urgent cases the model misses) of 3%, that is:
Missed cases/day=150×FNRwhich gives 4.5 missed cases/day at FNR = 3%, versus 15/day at FNR = 10%. That gap is why the acceptance threshold is negotiated on sensitivity, not overall accuracy: a model that is 97% accurate overall but has a 10% FNR on the urgent subgroup is missing three times as many critical cases as one with a 3% FNR.
Now suppose the shadow deployment observes 1,500 confirmed urgent cases over its run and the model misses 40 of them:
SE=np(1−p),p=150040=0.0267 95% CI=p±1.96⋅SE=0.0267±0.0081=[0.0185, 0.0348]So the observed FNR is about 2.67%, with a 95% confidence interval of roughly 1.85% to 3.48%. That interval is wide even with 1,500 urgent-case events, which is the practical argument for why shadow periods for rare, high-stakes subgroups need to run long enough (often across multiple sites, over weeks) to pin the estimate down tightly enough to make a go/no-go call with confidence, rather than reading too much into a single week of data.
Trade-offs & pitfalls
- The most common wrong turn: optimizing and reporting a single aggregate metric (AUC, accuracy) instead of the sensitivity/FNR split by subgroup that actually reflects clinical harm. A senior answer leads with the asymmetric-cost framing, not with a generic "we'll do an 80/20 train/test split."
- Skipping the silent/shadow stage and going straight from offline metrics to a clinician-facing pilot is the fastest way to discover a training-serving skew (systematic difference between how features were computed in training versus in the live serving path) as a patient-safety incident instead of a dashboard alert.
- Treating the prospective trial as a formality after the model is already "approved" internally, rather than as the actual gate: the stopping rules and non-inferiority margin must be able to kill the rollout, or they are theater.
- Over-indexing on model performance while under-specifying the human factors: if the UI doesn't clearly communicate uncertainty and the clinician silently starts rubber-stamping the model's suggestion (automation bias), the safety plan has a gap no amount of offline validation catches.
- Regulatory and compliance scope (for example FDA guidance on software as a medical device, or HIPAA for patient data handling) needs to be identified early, since it can change what evidence the trial has to produce, not bolted on after the pilot is already running.
Unlock Full Question Bank
Get access to all End-to-End ML System Design interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.