System Design Methodology and Trade-off Analysis Questions
The end-to-end approach to an open-ended design problem and the judgment that resolves it: clarifying scope and constraints, gathering functional and non-functional requirements, capacity and back-of-envelope estimation, and mapping requirements to a high-level architecture, then reasoning explicitly about competing options on cost, complexity, latency, and reliability to defend a choice. Covers driving a design interview from ambiguity to a proposal, trade-off frameworks, decision-making under uncertainty and incomplete information, reversible-versus-irreversible decisions, and defending choices under scrutiny. The process-and-judgment skill underneath every system-design case study.
How do you evaluate build-vs-buy for a core platform capability like authentication or observability? What technical, organizational, and financial criteria drive the decision?
Sample Answer
Direct answer
Build-vs-buy for a core platform capability like authentication or observability comes down to weighing three sets of criteria: technical (does the vendor cover the required functionality without excessive integration work), organizational (does the team have the skills and bandwidth to build and operate it, and is it a genuine differentiator worth owning), and financial (total cost of ownership over several years versus subscription cost, and the opportunity cost of the engineering time either path consumes). Commodity capabilities with real compliance or reliability requirements usually favor buying; capabilities that are a genuine competitive differentiator favor building.
Structured elaboration
Technical criteria: feature coverage against requirements (for authentication: single sign-on/OpenID Connect support, role-based access control; for observability: traces, metrics, logs, retention), integration complexity and API quality, scalability and the vendor's own reliability track record, and how hard it would be to migrate away later (portability, data export).
Organizational criteria: whether the team has the skills and spare capacity to build and operate this well, how urgent time-to-market pressure is, and whether this capability is a genuine long-term differentiator for the product or a commodity everyone needs and nobody differentiates on. Building a commodity capability is usually a distraction from what the team should be differentiating on.
Financial criteria: total cost of ownership (TCO) over a multi-year horizon (engineering time to build and maintain, hosting, licensing), the opportunity cost of the features that don't get built while the team builds this instead, and how predictable vendor pricing is versus the variability of an in-house maintenance burden.
This same framework generalizes beyond auth and observability. Adopting a search-as-a-service offering instead of operating a self-hosted search cluster turns on exactly the same criteria: cost, time-to-market, vendor lock-in, the quality of the vendor's service-level agreements (SLAs), and compliance requirements, the same list that applies to auth-as-a-service.
Worked example
Take authentication for a product with 500,000 monthly active users (MAU), comparing a managed identity provider against building in-house. Buy, at an illustrative $0.05 per MAU per month:
buy: 500,000 MAU×$0.05/MAU-month=$25,000/month⇒$25,000×36=$900,000 over 3 years
Build, assuming two engineers dedicated to building and operating it at an illustrative fully loaded cost of $180,000/year each:
build: 2 engineers×$180,000/year=$360,000/year⇒$360,000×3=$1,080,000 over 3 years
At this scale and time horizon, buying is roughly $180,000 cheaper over three years, before even counting the opportunity cost of the two engineers' time not going toward the product's actual differentiator. That gap would close or reverse at a different MAU count or a different per-MAU vendor price, which is exactly why this needs to be computed per situation rather than assumed.
Trade-offs & pitfalls
- The crossover point between build and buy moves with scale (MAU, request volume): a TCO comparison done once at launch can become wrong as the product grows, so it should be revisited, not treated as permanent.
- Vendor lock-in risk is real but is a cost to be mitigated (contract exit clauses, data portability, thin integration layers), not an automatic reason to build; building in-house has its own lock-in in the form of institutional knowledge walking out the door.
- A common weak answer treats "build" as inherently more control and "buy" as inherently faster, without pricing either side; the financial criterion is the one most often skipped under interview time pressure.
- Compliance requirements can flip the decision entirely regardless of cost: if a vendor can't meet a required certification, buy is off the table no matter how favorable the TCO looks.
Would you adopt a managed streaming service or build and operate your own in-house streaming platform, given uncertain future throughput growth? What would tip the decision one way or the other?
Sample Answer
Direct answer
Model the decision as an expected-cost comparison across a few throughput growth scenarios rather than a single guess, because the two options have very different cost shapes: buying scales cost with usage, building has a large fixed floor (upfront build cost plus a standing operations team) that only pays off once you're big enough and certain enough to need it. Uncertain growth favors the option with the lower fixed floor, usually managed, until a scenario is both large and likely enough that the fixed-cost floor gets amortized over enough throughput to win.
Structured elaboration
Modeling scenarios instead of one number
Pick 2-3 growth scenarios with probabilities from product's own forecast, not invented, price both options in each, and compare expected value:
EV=scenarios s∑P(s)×TotalCost(s)Worked example (illustrative unit rates, not vendor pricing)
Assume three throughput scenarios over a 3-year horizon: low (30% probability, 50k messages/sec sustained), medium (50%, 150k messages/sec), high (20%, 500k messages/sec).
Managed service cost model: $2,000/month baseline plus $50/month per 1,000 messages/sec of sustained throughput:
Low: 2,000+50×50=$4,500/month,×36 mo=$162,000 Medium: 2,000+50×150=$9,500/month,×36=$342,000 High: 2,000+50×500=$27,000/month,×36=$972,000 EVbuy=0.3(162,000)+0.5(342,000)+0.2(972,000)=$414,000In-house build cost model: $150,000 one-time build, a capital expenditure (CapEx), plus a 2-person operations team at $180,000/year each ($360,000/year, or $1,080,000 over 3 years), plus cheaper infrastructure at $20/month per 1,000 messages/sec:
Low infra: 20×50×36=$36,000;total=150,000+1,080,000+36,000=$1,266,000 Medium infra: 20×150×36=$108,000;total=$1,338,000 High infra: 20×500×36=$360,000;total=$1,590,000 EVbuild=0.3(1,266,000)+0.5(1,338,000)+0.2(1,590,000)=$1,366,800At these illustrative rates, the managed option wins by a wide margin across every scenario, because the standing operations team's fixed cost dominates the build side regardless of which throughput scenario materializes. What would flip it: a much smaller required operations team (a shared platform team rather than a dedicated one), a much longer horizon over which to amortize the CapEx, or a high-throughput scenario likely and large enough that the managed service's linear per-unit cost overtakes the build floor.
The same axis, a different pair (absorbed angle): serverless versus self-run Kubernetes
The identical logic applies to choosing a compute platform under uncertain load: a self-run Kubernetes cluster has a fixed floor too, an always-on control plane and the operations team that keeps it patched and tuned, the same shape as the in-house streaming build. Serverless functions mirror the managed service's usage-scaled cost. Under uncertain or bursty demand, serverless, like the managed stream, avoids paying for a fixed floor that might not be needed; once load is large and predictable enough, the fixed floor of a self-run cluster, like in-house streaming, can undercut the usage-based price per unit.
Trade-offs & pitfalls
- Pitfall: comparing sticker prices at today's throughput instead of expected cost across the range of plausible futures; a single-point estimate hides exactly the uncertainty this question is about.
- Non-monetary factors that can outweigh the number: time-to-market, whether the operations expertise a self-run platform needs can even be hired, vendor lock-in risk, and roadmap alignment with what the managed provider is building next.
- A pilot or a contractual off-ramp (a short commitment with defined exit terms) reduces the risk of the wrong choice by buying time to observe which growth scenario is actually happening before committing further.
- Watch for the build side's operations team being understaffed in the estimate; a streaming platform run by 2 people that actually needs 4 will blow the model above badly.
A client tells you: 'our web application must feel fast for users worldwide.' How would you translate that into concrete, measurable non-functional requirements?
Sample Answer
Direct answer
Translate "feels fast" into measurable, percentile-based service-level objectives (SLOs, the internal targets a team designs to) broken out by user geography and device class, because a single global average latency number hides the users who are actually having a bad experience. Concretely: pick a small set of user-perceived timing metrics, set targets for the 95th and 99th percentile (P95/P99), not just the median, and set different targets per region, since physics, not engineering effort, sets a latency floor for users far from the servers.
Structured elaboration
Why percentiles, not averages
The median (P50) reflects the typical user; P95 and P99 reflect the users who are actually complaining, and those are the ones a business should worry about losing.
Candidate user-perceived metrics (standard web-performance terms, named here without inventing a universal target for each, since the right target is a product decision):
- Time to First Byte (TTFB): how long until the server starts responding.
- First Contentful Paint (FCP): how long until something appears on screen.
- Time to Interactive (TTI): how long until the page actually responds to input.
Segmentation
- By region: a request served from a single origin has a very different latency floor depending on how far the user is from that origin (worked example below).
- By device and network class: a phone on a mobile network experiences different bandwidth and queuing behavior than a laptop on a wired connection; the specifics of that are their own topic, but the targets should differ, not share one number.
From target to commitment
An SLO is the internal target a team designs to; a service-level agreement (SLA) is the external, often contractual, promise made to a customer. The SLA should sit inside the SLO with room to spare (an error budget: the amount of time the SLO is allowed to be missed before it counts as a real problem), otherwise there is no margin for a bad day.
Worked example
Physics sets a hard floor before any engineering happens. Light in fiber travels at roughly 200,000 km/s (about two-thirds the speed of light in vacuum, due to the refractive index of glass). If a user in Mumbai is served from a single origin server in Virginia, the one-way great-circle distance is roughly 12,000 km:
tone-way=vd=200,000 km/s12,000 km=0.06 s=60 ms
RTTmin=2×tone-way=120 ms
That is the theoretical best case for one round trip before the server does any work at all, and a real page load needs several round trips (DNS lookup, then a TCP/TLS handshake, then the actual request), so a single-origin design cannot hit an aggressive global P95 no matter how fast the backend code is. This is the concrete argument for a content delivery network (CDN, a network of edge servers that cache content closer to users) or a multi-region deployment: it is not a nice-to-have, it is the only way to shrink the distance term in the equation above for users far from wherever the service is deployed.
Trade-offs & pitfalls
- Setting one global latency target and being surprised it's missed for distant regions; the fix is a region-aware target, not "optimize the backend more."
- Optimizing for the average and declaring victory while P95/P99, and the users behind them, stay slow.
- Promising an SLA as tight as the internal SLO, leaving no error budget for a bad day.
- The cost trade-off worth naming explicitly: hitting a tight worldwide P95 costs real money (CDN, edge compute, multi-region infrastructure and replication). "How fast" is really "how much are we willing to spend to move the physical floor closer to zero," and that should be a deliberate decision, not an assumed one.
You're responsible for two services on the same platform: payment processing and product catalog browsing. If the network partitions, would you prioritize consistency or availability for each service, and why do the two answers differ? What metrics or failure modes would you point to in order to defend treating them differently?
Sample Answer
Direct answer
Payment processing should favor consistency during a network partition, and product catalog browsing should favor availability, because the two operations have opposite costs when they go wrong: an inconsistent payment can create a real financial loss or a double charge, while a stale catalog page is a minor, self-correcting annoyance. The right lens is not "which service is more important" but "what does staleness or unavailability actually cost for this specific data," which is exactly why the same platform can, and should, make opposite choices for its two services.
Structured elaboration
Decision criteria, side by side
| Dimension | Payment processing | Product catalog browsing |
|---|---|---|
| Cost of a wrong or stale read | Financial loss, chargebacks, regulatory exposure | User briefly sees an item as in stock when it isn't; corrected on the next read |
| Cost of unavailability | User retries or the checkout fails visibly; recoverable | Users abandon browsing entirely if the whole catalog looks down |
| Write pattern | Low volume, high value, correctness-critical | Read-dominated, high volume |
| Recoverability | Hard to undo once money has moved | Self-heals as soon as fresher data is read again |
Metrics that would defend the split, if challenged
- Payment: commit latency (P95/P99, 95th/99th percentile), and abort/retry rate. A rising abort rate under partition is the system correctly refusing to guess; a rising rate of duplicate-charge incidents would mean the consistency posture failed.
- Catalog: replica lag (a staleness window measured in seconds) and cache hit rate. A growing staleness window is the visible cost of the availability-first choice, and it should have an agreed ceiling (a service-level objective, SLO) rather than being left open-ended.
Mechanism, named but not re-derived
Payment typically uses a majority-quorum write (a quorum is the minimum number of replicas that must agree before a read or write counts as successful) against a small number of strongly consistent replicas (or a single-leader transactional database); catalog typically uses asynchronous replication with read replicas and edge caching. The internals of quorum protocols and cache invalidation are their own topics; what matters here is that these are two different, deliberate consistency configurations applied to the same platform.
Worked example
Take a five-node deployment (N = 5) split across three data centers, and a partition that isolates 2 nodes from the other 3. Two pieces of notation carry the arithmetic below: W is how many replicas must acknowledge a write before it counts as done, and R is how many must respond to a read before it is returned to the caller; AP and CP name the two postures, AP meaning the system favors Availability over Consistency when the network Partitions, CP meaning it favors Consistency over Availability instead.
Catalog (AP): W = 1, R = 1. Either side can serve any single reachable node.
majority side: 3≥1,minority side: 2≥1
Both sides stay available. The risk: the two sides may accept conflicting updates to the same catalog item (say, a price change), which gets reconciled (for example, by last-write-wins on a timestamp) once the partition heals.
Payment (CP): majority-quorum writes, requiring W = ⌈(N+1)/2⌉ = 3 acknowledgments.
Wmaj=⌈2N+1⌉=⌈25+1⌉=3
majority side: 3≥3⇒quorum reachable, writes continue
minority side: 2<3⇒quorum unreachable, writes must be refused
The same partition event produces two different outcomes on purpose: the catalog stays available everywhere and quietly reconciles later; payment processing keeps working on the majority side and explicitly refuses new authorizations on the minority side, rather than risk two systems each thinking they alone authorized the same order.
The same reasoning generalizes to other service pairs on a platform. A shopping cart during a partition usually leans AP too: accepting an item add on whichever side is reachable and merging any duplicate or conflicting cart state once the partition heals costs less (in lost conversions) than blocking the add. An ML feature store splits the same way payments and catalog do: the online serving path leans AP (serve the last known feature value within a freshness window), while the offline training-data snapshot leans CP (a training run built from a partially-written snapshot silently corrupts the model, so it waits for a consistent point-in-time view).
Trade-offs & pitfalls
- Defending the split with an opinion ("payments feel important") instead of naming a concrete cost of staleness or downtime and a metric that would catch a violation of the chosen posture.
- Assuming the whole platform must share one CAP posture; a mature platform is a portfolio of per-service, sometimes per-operation, decisions.
- Choosing CP for payment but forgetting the user-facing failure path: what checkout shows when the minority side can't reach quorum matters as much as the backend behavior. A clear "please try again" beats a silent hang.
- Naming, without re-deriving, that idempotency keys (a unique identifier attached to a request so that retrying it after a timeout or failure cannot accidentally apply the same charge twice) and compensating transactions let a team take a calculated availability risk on payment writes without producing duplicate charges; that mechanism belongs to a different topic, but knowing it exists is part of a complete answer here.
You suspect a bottleneck in one service, but you're not certain yet. Before committing to a major architectural change to fix it, how would you cheaply validate that the bottleneck is real and where it actually is?
Sample Answer
Direct answer
Before committing to a major architectural change, validate the suspected bottleneck with the cheapest experiment that can confirm or rule it out: add lightweight instrumentation or profiling to the suspect service, replay realistic load against it in an isolated environment, and check whether the metric you expect to be saturated (CPU, a lock, a downstream call) actually is, before touching the architecture.
Structured elaboration
State the hypothesis precisely. Not "service X is slow," but something falsifiable: "service X's latency under load is dominated by contention on resource Y, and relieving it should cut p95 (95th-percentile) latency by roughly Z%." A vague hypothesis can't be cheaply disproven.
Pick the minimal instrumentation. Add or enable, behind a feature flag if possible: request latency percentiles (p50/p95/p99), resource metrics (CPU, memory, disk input/output operations per second), and lightweight sampling profiles or distributed traces that show where time is actually spent inside a request. The goal is the smallest change that produces evidence, not a full rewrite.
Isolate the variable. Run the suspect service in a canary or staging environment that mirrors production configuration, and drive it with load that matches real traffic shape (replayed or recorded traffic is more trustworthy than synthetic load that doesn't match the real access pattern).
Define a falsifiable success criterion up front. For example: if the suspected resource explains most of the added latency and a small, reversible change to it measurably improves the target metric without regressing others, the hypothesis holds. If not, the data should point toward the next candidate (a different resource, a downstream dependency), not toward abandoning the investigation.
Worked example
An illustrative scenario: you suspect an internal service is CPU-bound under load. Before proposing a rewrite or a scaling change, you'd enable request tracing for a sample of traffic and look at where time is spent inside a request: if profiling on a canary shows the bulk of request time inside a single expensive downstream call rather than inside the service's own processing, that redirects the investigation entirely, toward the downstream dependency or a caching layer in front of it, rather than toward scaling or rewriting the service you originally suspected. The point of the exercise is that this kind of evidence is cheap to gather (a canary, a load replay, existing tracing infrastructure) compared to committing engineering months to an architectural change aimed at the wrong target.
Trade-offs & pitfalls
- Skipping validation and going straight to an architectural fix risks solving a problem that doesn't exist, or solving the wrong one, while the real bottleneck (often a downstream dependency, a lock, or a misconfigured connection pool) goes untouched.
- A load test that doesn't match real traffic's shape (arrival pattern, request mix, payload sizes) can validate the wrong hypothesis just as confidently as a matching one; recorded or replayed real traffic is more trustworthy than a uniform synthetic load generator.
- Correlated resource metrics can mislead: high CPU and high latency occurring together doesn't prove CPU caused the latency; confirm causation by changing the resource and observing the metric move, not just by observing them move together.
- Keep the validation experiment cheap and reversible (a feature flag, a canary, a short-lived load test) so a wrong hypothesis costs little to rule out.
Unlock Full Question Bank
Get access to all System Design Methodology and Trade-off Analysis interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.