Skip to content

Senior Engineering Interview Handbook / Chapter 74

What the System-Design Interview Tests

A close reading of one system-design round that separates architecture knowledge from the observable evidence of senior engineering judgment.

The diagram is not the answer

Forty minutes into a system-design interview, a candidate has drawn a plausible notification service: API, database, queue, workers, provider adapters, and a cache. Every component belongs. The arrows point in sensible directions. Asked how the round went, the candidate says, “I got to the right architecture.”

The interviewer’s notes say something else:

Unclear what "accepted" means.
Did not distinguish transactional messages from campaigns.
Preference changes after enqueue were unresolved.
Added retries, but did not explain duplicate sends.
Kept expanding the diagram after the provider-failure prompt.

The candidate may know the architecture. The interview did not make that knowledge sufficient evidence.

A system-design round is a compressed design review. The prompt is underspecified, the clock is hostile to completeness, and the interviewer can observe only the decisions you make visible. They are not evaluating whether your diagram matches a hidden reference answer. They are trying to predict how you would frame an ambiguous problem, organize it, choose under pressure, and revise a design when reality resists the first version.

That is the threshold between the systems foundations in the preceding part and the system-design method that follows. Architecture knowledge supplies the possible moves. The round tests whether you can choose among them.

A system-design evidence map with observable evidence at the center and six surrounding signals: frame, model, trade off, scale, operate, and steer.
The interviewer cannot score private knowledge. Framing, modeling, trade-offs, scale reasoning, operational judgment, and steering make it observable.

Begin with the decision the prompt is hiding

Return to the notification prompt:

Design a service that sends email, SMS, and in-app notifications.

It invites a familiar component diagram, but several different products fit inside that sentence. A password-reset system cannot casually lose or delay a message. A marketing campaign must respect consent and suppression. An in-app activity feed may tolerate delay and collapse repeated events. A tenant-wide incident can create a burst that normal traffic averages conceal.

Requirement discovery is not measured by the number of questions asked. It is measured by whether the questions uncover a decision. A useful opening might be:

Are we handling transactional notifications, campaigns, or both? What does the caller believe after we accept a request: that it is durably recorded, or that a provider has delivered it? Can a user change channel preferences while work is already queued?

Each answer changes the design. Message class affects priority and policy. The meaning of acceptance determines the write boundary. Late preference changes determine whether suppression is checked only at ingestion or again at dispatch.

Discovery must become prioritization. Suppose the interviewer answers: both transactional and campaign traffic; acceptance means durable responsibility; preference changes should stop unsent campaign messages; provider delivery remains outside the service’s control. The candidate can now state a compact contract:

Accept a request only after durable recording.
Protect transactional work from campaign bursts.
Suppress duplicates by caller-supplied idempotency key.
Recheck campaign eligibility before dispatch.
Expose delivery attempts without promising provider receipt.

This is already senior evidence. The candidate has turned an open prompt into a product promise, ranked correctness above optional throughput, and named a boundary the system cannot guarantee. No technology choice could have done that work.

Decomposition reveals what the boxes protect

Weak decomposition is a parts list. Strong decomposition separates kinds of truth and kinds of work.

For this service, the durable notification request is not the same thing as a provider attempt. User preferences are not owned by the dispatch worker. Rendered message content is not necessarily safe to retain forever. Campaign scheduling, eligibility, dispatch, provider interaction, and status reporting fail in different ways.

Before adding services, the candidate can name the state:

  • A notification request records tenant, recipient, type, priority, template reference, channel policy, and idempotency key.
  • Eligibility depends on preferences and suppression rules owned by the appropriate profile or policy system.
  • A dispatch job is derived work. It can be retried or rebuilt from durable request state.
  • A provider attempt records a bounded interaction and its result class; it does not redefine whether the original request was accepted.

Now the first architecture has reasons. The request API owns durable acceptance and duplicate suppression. A scheduler or dispatcher creates channel work. Priority-separated queues prevent a campaign from consuming the capacity needed for password resets. Workers enforce current policy, call providers, and record attempts. Status reads are built from request and attempt state.

This is decomposition as an evaluative signal: the candidate can divide a large problem along ownership, consistency, policy, and failure boundaries. The diagram becomes a consequence of the model instead of a memory test.

Breadth earns the right to depth

The round is too short for a complete production design. Breadth and depth are therefore tested together.

Breadth means noticing the dimensions that could invalidate the first design: traffic shape, storage growth, provider quotas, hot tenants, privacy, authorization, abuse, observability, regional failure, rollout, and cost. It does not mean delivering a sentence about every one of them. A candidate who says “we would also add security, monitoring, and multi-region” has named a catalog, not reasoned across a system.

Depth means following one consequential path until its mechanism is credible. For the notification service, provider failure is a natural deep dive because it touches durable state, retries, duplicate effects, queue pressure, and the meaning of delivery.

The candidate should first show enough breadth to choose that depth:

The main pressures I see are campaign bursts, preference correctness, duplicate sends, provider quotas, and delayed high-priority work. I want to deepen provider failure because it crosses the acceptance boundary and can amplify both duplicates and queue age.

That sentence is selective without being narrow. It shows awareness of the system around the chosen path and gives the interviewer a chance to redirect. During the deep dive, the candidate can distinguish transient provider errors, permanent address failures, throttling, ambiguous timeouts, and local worker failure. Those cases justify different actions. A timeout after sending may have produced a message even though no response arrived; blind retry can create a duplicate. More workers cannot defeat a provider quota; they may only increase contention and retry traffic.

Depth is not the number of implementation details supplied. It is how far the reasoning survives contact with a hard case.

A trade-off needs a losing option

Interview answers often use “trade-off” to introduce two agreeable lists. Actual design requires a choice.

Suppose the candidate proposes checking campaign preferences again when a worker is ready to dispatch. The choice improves correctness after an opt-out, but it adds a dependency to the hot path. Caching preferences reduces that load, but stale cache entries can send messages that policy says to suppress. Cancelling queued jobs on every preference change avoids some reads, but makes queue cancellation and races part of the correctness model.

A defensible decision has four pieces:

Constraint: campaign opt-outs must affect work that has not been sent.
Choice: recheck eligibility at dispatch, with a short bounded cache only for
        policy categories where brief staleness is explicitly allowed.
Cost: extra policy reads and possible dispatch delay.
Reversal: if policy reads cannot meet the required availability, copy a
          versioned suppression projection into the dispatch domain and prove
          its propagation bound.

The rejected options matter because they reveal the decision rule. “Use a cache for scale” displays a tool. Choosing where stale policy is unacceptable displays judgment.

Good trade-off reasoning also keeps scope honest. The first design need not solve provider selection, template authoring, campaign analytics, and global data residency at once. It should say which of those are excluded, which extension points remain, and which omitted concern would force a different architecture.

Reliability is behavior, not decoration

When an interviewer asks, “What happens if the SMS provider is down?”, they are not requesting the words retries, backoff, dead-letter queue, and monitoring. They are asking whether the candidate can preserve the system’s promise during failure.

A strong answer follows the state:

  1. The accepted request remains durable even if dispatch cannot proceed.
  2. A worker records each provider attempt with a stable notification identity.
  3. Retryable failures return to delayed work with a bound, backoff, and jitter; permanent failures become terminal.
  4. An ambiguous timeout remains ambiguous. The system does not pretend that transport failure proves non-delivery.
  5. A fallback provider is used only when policy permits it and duplicate risk is understood.
  6. Queue age and high-priority delivery success expose user harm before worker CPU does.

Notice the order: promise, state, behavior, limit, evidence. Reliability is not a collection of components added to the right side of the drawing. It is what the system does after one of its assumptions stops holding.

The same test applies to scale estimates. “Ten million messages per hour” is not impressive by itself. If that estimate reveals that a provider quota is lower than arrival rate, then it should change admission, priority isolation, queue capacity, customer expectations, and alerting. A number becomes senior evidence only when it moves a decision.

Communication makes the reasoning inspectable

The interviewer cannot follow a design whose structure exists only in the candidate’s head. Communication here is not smooth delivery or drawing talent. It is control over shared attention.

Useful signals are small:

  • name the decision currently being made;
  • label assumptions near the part of the design that depends on them;
  • summarize before moving from the write path to a failure deep dive;
  • distinguish observation, assumption, and choice;
  • invite direction when two deep dives would both be valuable;
  • stop adding architecture when the remaining time is needed for risks and a conclusion.

For example:

I have established durable acceptance and the dispatch boundary. Before I add regional placement, I see two useful risks: ambiguous provider outcomes and campaign isolation. I think the first is more central to correctness; would you like me to take that deeper?

This is not asking the interviewer to design the answer. It proves that the candidate can preserve a coherent review while making good use of another engineer’s attention.

Adaptability is visible revision

Near the end of the round, the interviewer changes one fact:

Enterprise customers require notification requests and delivery history to remain in a specified region.

A rigid candidate mentions regional databases and continues with the original diagram. An adaptable candidate identifies which decisions have become invalid:

That changes placement from an optimization to a correctness constraint. I would route by tenant residency before durable acceptance, keep request and attempt state in-region, and verify whether each provider’s processing and failover path satisfies the same boundary. A global queue can no longer carry message content casually. I would use regional dispatch planes and a minimal global control plane that contains no restricted payload. This also means cross-region failover may be unavailable for some tenants, so the availability promise must say so.

Adaptability is not agreeing quickly or replacing the design theatrically. It is tracing the new constraint through the existing decisions, preserving what still works, and naming the new cost. The interviewer learns that the candidate is attached to the problem rather than to the first answer.

What survives the debrief

Interviewers usually reduce a long conversation to a short hiring discussion. The useful evidence from this round is not “used a queue” or “knew about idempotency.” It sounds more like this:

Discovered that message class and late preference changes altered the design.
Defined durable acceptance without claiming provider delivery.
Separated request truth, policy ownership, dispatch work, and provider attempts.
Prioritized transactional traffic over campaign bursts.
Covered the system broadly, then chose ambiguous delivery for a credible deep dive.
Defended a dispatch-time policy check and named its availability cost.
Traced provider failure through retries, duplicates, queue age, and user impact.
Kept the review navigable and revised regional placement when residency changed.

That note contains the outline of senior performance: requirement discovery, decomposition, prioritization, breadth, depth, trade-offs, reliability, communication, and adaptability. None is a personality trait. Each is a behavior the round made observable.

You can test your own answer the same way. After a mock, close the diagram and write the interviewer’s debrief from memory. Record only decisions supported by something you actually said or drew. If the note contains mostly component names, the next practice session does not need a more exotic system. It needs clearer evidence: one question that changes architecture, one explicit priority, one boundary tied to owned state, one chosen trade-off, one failure traced to user harm, and one revision under a changed constraint.

The chapters ahead provide the operating sequence and the technical moves. Begin with The System-Design Interview Framework, which turns this evidence into a path through the clock. The rule to carry forward is simpler: architecture knowledge counts when another engineer can see how you used it.