System Design Methodology
How to run a system design interview — gathering functional and non-functional requirements, capacity estimation, availability budgets, API style choice, HLD versus LLD, and common pitfalls.
8 questions
JuniorTheoryVery commonHow do functional and non-functional requirements differ in system design?
How do functional and non-functional requirements differ in system design?
Functional requirements say what the system does: user roles, permissions per role, keyword search with filters, and supported payment methods. Non-functional requirements say how well: DAU/MAU, growth, the read/write ratio, retention, and latency targets.
Common mistakes
- ✗Listing only features and forgetting non-functional numbers like DAU, growth, and the read/write ratio
- ✗Treating latency and availability targets as functional requirements instead of non-functional ones
- ✗Diving into the architecture before any requirement is written down with the interviewer
Follow-up questions
- →Which non-functional number most shapes the architecture, and why?
- →How would the read/write ratio change your storage and caching choices?
MiddleDesignVery commonA marketplace has 30M daily active users (DAU), each doing 8 actions/day, item uploads of 500KB, an 80/20 read/write ratio, 3-year retention, and a 5x daily peak — estimate average and peak queries per second (QPS), yearly storage and bandwidth, and name the components those numbers stress.
A marketplace has 30M daily active users (DAU), each doing 8 actions/day, item uploads of 500KB, an 80/20 read/write ratio, 3-year retention, and a 5x daily peak — estimate average and peak queries per second (QPS), yearly storage and bandwidth, and name the components those numbers stress.
Average write QPS = 30M8/86400 ≈ 2.8k; peak = 2.8k5 ≈ 14k, and at 80/20 reads peak near 56k. Storage/year = items/day500KB3y; bandwidth tracks peak reads. Those numbers stress the write path, object store, and read cache — justifying sharding and a CDN.
Common mistakes
- ✗Skipping estimation entirely and jumping to architecture, so component choices have no numeric justification.
- ✗Computing peak by dividing the average by the peak factor instead of multiplying, undersizing the system.
- ✗Forgetting the read/write ratio, so read capacity and bandwidth for the heavy read path are never sized.
Follow-up questions
- →Where in the day does the 5x peak fall, and what triggers it?
- →Which estimated number would most change your storage tier choice?
MiddleDesignVery commonDesign a high-level architecture for a marketplace order service (sellers, buyers, payments), then explain how that HLD differs from the low-level design you would write afterward.
Design a high-level architecture for a marketplace order service (sellers, buyers, payments), then explain how that HLD differs from the low-level design you would write afterward.
HLD is boxes and arrows: services, data stores, and queues with labeled data flow. Draw it starting from the user, assume one datacenter, and avoid cyclic dependencies. LLD comes after — schemas, indexes, API signatures, and struct/interface design.
Common mistakes
- ✗Jumping straight to table schemas and index choices instead of first drawing services, stores, and labeled data flow.
- ✗Drawing arrows between services without labels, so nobody can tell what data or request actually crosses each edge.
- ✗Allowing cyclic dependencies between services on the HLD, which makes ownership and deploy order impossible to reason about.
Follow-up questions
- →Where on this HLD does payment go, and which arrow carries the order event?
- →How would you split this single box into concrete tables and indexes in LLD?
JuniorTheoryCommonWhen do you choose REST over gRPC for a service, and why?
When do you choose REST over gRPC for a service, and why?
Pick REST for external, public, human-debuggable APIs you want cacheable and easy to call from browsers. Pick gRPC for internal service-to-service calls: binary protobuf, HTTP/2 streaming, typed contracts, lower latency. Justify by internal-vs-external plus streaming needs.
Common mistakes
- ✗Claiming gRPC is universally faster and defaulting to it even for public, browser-facing endpoints.
- ✗Treating REST and gRPC as interchangeable and never justifying the pick by internal-vs-external.
- ✗Forgetting that gRPC streaming and typed protobuf contracts are its real edge, not just speed.
Follow-up questions
- →How does gRPC streaming change the design versus request-response REST?
- →Why is REST easier to cache and debug at the network edge?
MiddleTheoryCommonHow do SLA, SLO, and SLI differ, and how do they relate to non-functional requirements?
How do SLA, SLO, and SLI differ, and how do they relate to non-functional requirements?
SLA is the contractual external promise to customers, with money penalties if you breach it. SLO is the stricter internal target you steer toward — set it tighter so you alert before the SLA is at risk. SLI is the measured indicator the SLO is defined on, like p99 latency or success rate. They turn fuzzy non-functional requirements into numbers, and you never promise nines you cannot pay for.
Common mistakes
- ✗Swapping the definitions — calling the SLA the internal target and the SLO the customer contract
- ✗Promising nines in the SLA with no SLI measured and no SLO margin to alert before a breach
- ✗Treating SLA/SLO/SLI as disconnected from the non-functional requirements that should set them
Follow-up questions
- →Why set the SLO stricter than the SLA instead of making them equal?
- →Which SLIs would you pick for a write-heavy marketplace API?
JuniorTheoryOccasionalWhat do 99.9% and 99.99% availability mean in yearly downtime, and why does each extra nine cost more?
What do 99.9% and 99.99% availability mean in yearly downtime, and why does each extra nine cost more?
Availability is the fraction of a year a service is up, so the leftover is your downtime budget. 99.9% (three nines) allows about 8.76h/year, while 99.99% (four nines) drops that to roughly 52.6min/year. Each added nine cuts the budget ~10x, so it roughly multiplies the cost and engineering complexity by ~10x — redundancy, failover, and testing all grow.
Common mistakes
- ✗Saying 99.9% is
52.6min/year (that is 99.99%) — confusing three nines with four nines - ✗Promising five nines without the redundancy and on-call budget to actually back it up
- ✗Treating each extra nine as a small linear cost rather than a roughly 10x jump in effort
Follow-up questions
- →How do SLA, SLO, and SLI differ, and which one carries financial penalties?
- →Which architectural changes buy you the jump from three nines to four nines?
SeniorDesignOccasionalYou have just finished designing a Go marketplace service backed by one Postgres instance, and the interviewer asks how you would make it operationally ready before it carries real production traffic. Treat the design itself as settled — the question is only about operability. Constraints: a multi-service deployment where a single user request fans out across several Go services; data loss is unacceptable and the schema will keep evolving release after release; the team must be able to detect and diagnose incidents quickly. Describe the operational practices you would put in place, in what order you would adopt them, and how you decide when to move beyond the single Postgres.
You have just finished designing a Go marketplace service backed by one Postgres instance, and the interviewer asks how you would make it operationally ready before it carries real production traffic. Treat the design itself as settled — the question is only about operability. Constraints: a multi-service deployment where a single user request fans out across several Go services; data loss is unacceptable and the schema will keep evolving release after release; the team must be able to detect and diagnose incidents quickly. Describe the operational practices you would put in place, in what order you would adopt them, and how you decide when to move beyond the single Postgres.
Set up backups — full, incremental, and point-in-time — and prove them with a tested restore, because an untested backup is not a backup. Use forward-only versioned schema migrations, add metrics and monitoring, and add distributed tracing to follow one request across services. Start with the single Postgres and scale out only when a requirement forces it.
Common mistakes
- ✗Listing backups but never proving them with a restore drill; an untested backup silently fails the day you need it.
- ✗Treating ad-hoc or reversible schema edits as fine; non-versioned changes drift environments and break replays.
- ✗Skipping distributed tracing, so a request that fans out across Go services becomes impossible to follow end-to-end.
Follow-up questions
- →Which restore-time target decides between point-in-time and nightly full backups?
- →When does a concrete requirement justify moving beyond the single Postgres?
SeniorTheoryRareWhat are the classic system design interview pitfalls, and what discipline keeps a design out of them?
What are the classic system design interview pitfalls, and what discipline keeps a design out of them?
Reaching for tech you don't understand, designing past the requirements, dumping every fact to show off, ignoring product metrics, and over-engineering. The discipline is to start simple and add complexity only when a concrete requirement forces it.
Common mistakes
- ✗Listing pitfalls but not naming the cure: start simple and scale only when a requirement demands it.
- ✗Treating over-engineering as caution; unused caches and queues add failure modes with no benefit.
- ✗Confusing showing breadth with depth; reciting every fact ignores the actual requirements and metrics.
Follow-up questions
- →When does a concrete requirement justify adding a cache or a queue?
- →How do product metrics change which component you optimize first?