system-design

The 25 Most Common Mistakes

A checklist of the specific ways candidates lose points, gathered in one place. Read it before every mock. Most failures are one of these — and most are entirely avoidable.

Prerequisites: The Framework Time to read: ~14 minutes


How to use this

🚨 These are patterns, not obscure traps. The majority of interview failures come from a handful of avoidable behaviours, and knowing the list lets you catch yourself. Read it before each mock; after each mock, check which ones you committed. (Each links to the chapter that fixes it.)


Process mistakes (the framework)

1. Jumping straight to a solution. Drawing boxes before clarifying requirements. Signals inexperience immediately. → Requirements Gathering

2. Not scoping / trying to design everything. “Design Instagram” attempted in full → everything shallow, nothing deep. → Requirements

3. Never reaching a design. Spending 25 minutes on requirements/estimation and running out of time. The top time-management failure. → The Framework

4. Not stating a plan. Diving in without “here’s how I’ll structure this.” → The Framework

5. Poor time management. Going too deep too early, or too shallow everywhere. → The Framework


Estimation mistakes

6. Skipping estimation. Not sizing the system → the design isn’t grounded in scale. → Estimation

7. Silent arithmetic. Doing math without narrating → scores nothing.

8. Not using the numbers. Computing 450K QPS and not saying “so we need a cache.” The biggest estimation waste. → Estimation

9. Forgetting peak. Designing for average → down every evening.


Design mistakes

10. Boxes with no justification. Every component must earn its place. → Deep Dives

11. Over-engineering. 🚨 Sharding, microservices, multi-region for a small system. Signals poor judgment — the opposite of what over-preparers expect. → 1 to a billion

12. Not starting simple. Drawing the final complex architecture instead of evolving. → 1 to a billion

13. Exposing the database schema as the API.API Principles

14. Unbounded list endpoints / no pagination.Pagination

15. Not walking the read/write paths. Static boxes, no data flow. → The Framework


Technical/depth mistakes

16. Staying at level 1. Naming components without going deep. → Deep Dives

17. No trade-offs / reciting. The mid-level ceiling. The single most common depth failure. → Trade-off Vocabulary

18. Ignoring failure. Only the happy path. “What if X fails?” has no answer. → Failure Modes

19. Claiming exactly-once delivery. Impossible; say at-least-once + idempotent. → Idempotency

20. No idempotency for payments/orders. Retries cause double charges. → Idempotency

21. Ignoring the celebrity/hot-key problem in feed designs. → Hot Keys

22. Confusing consistency concepts (ACID’s C vs CAP’s C; strong vs eventual per data type). → Consistency, CAP


Communication/behaviour mistakes

23. Silence. 🚨 Not narrating. The interviewer can’t evaluate what you don’t say — the most damaging behaviour. → The Framework

24. Bluffing when you don’t know. Worse than reasoning honestly. → Handling Uncertainty

25. Defensiveness / ignoring hints. Arguing when challenged, or not taking the interviewer’s repeated hints. → Deep Dives, Handling Uncertainty


The top 5, if you remember nothing else

🚨 If you internalize only five, make it these — they cause the most failures:

  1. Requirements first — never jump to a solution. (#1)
  2. State trade-offs — reciting components is the mid-level ceiling. (#17)
  3. Narrate constantly — silence is the most damaging behaviour. (#23)
  4. Handle failure — “what if it fails?” for every component. (#18)
  5. Start simple, don’t over-engineer — premature complexity signals poor judgment. (#11, #12)

The over-preparer’s paradox

🚨 A specific trap for people who’ve studied hard: knowing all the advanced techniques tempts you to use them all — sharding, microservices, Kafka, multi-region — for a system that needs none of it. This over-engineering (#11) signals worse judgment than a simpler design, because senior engineering is knowing what not to build.

🎙️ The counter-move: propose the simplest thing that meets the requirements, and justify complexity only when the numbers demand it. “This handles our scale with one Postgres and a cache; I’d revisit sharding at 10× growth.” Restraint scores higher than sophistication. → Trade-off Vocabulary


🎙️ Soundbites (the corrections)


🛠️ Try it

1. Post-mock checklist. After every mock, go through all 25 and mark which you committed. Your recurring ones are your personal weak spots — the highest-value thing to fix.

2. Pre-mock reminder. Before each mock, read the top 5. Priming yourself to avoid them makes it more likely you will.

3. Record and audit. Record a mock, then watch it specifically hunting for silence (#23), missing trade-offs (#17), and unjustified boxes (#10). Seeing yourself commit them is more corrective than reading about them.

4. Deliberately over-engineer, then simplify. Design a small system with maximal complexity (sharding, microservices, multi-region), then redesign it simply. Feel how the simple version is the better answer — internalizing the over-preparer’s paradox.


Check yourself

1. Why is jumping straight to a solution such a damaging mistake? Because it signals inexperience immediately and risks designing the wrong system. When a candidate hears "Design Instagram" and starts drawing boxes within seconds, they demonstrate the junior instinct to pattern-match to a solution before understanding the problem — which is exactly what distinguishes an inexperienced engineer from a seasoned one, who knows that real problems are ambiguous and must be scoped and clarified first. Practically, it's dangerous because without gathering requirements (scale, read/write ratio, consistency needs, latency targets), you don't know what you're designing *for*, so you can produce a beautiful architecture that's completely wrong for the actual constraints — a strongly- consistent design when eventual would do, or a single-region design when the requirement was global, or a write-optimized design for a read-heavy system. The non-functional requirements *drive* the architecture, and you can't know them without asking. So jumping to a solution both makes a poor first impression (signaling you don't know to clarify first) and undermines the technical quality of everything that follows (since it's un-grounded in the real requirements). It's consistently one of the top ways candidates fail, and it's entirely avoidable — the fix is simply to spend the first several minutes on requirements and scoping before any design, which itself signals experience.
2. Why does over-engineering signal *worse* judgment than a simpler design? Because senior engineering is fundamentally about knowing what *not* to build, and reaching for advanced techniques a system doesn't need demonstrates the opposite — an inability to match solution complexity to actual requirements. When a candidate proposes sharding, microservices, Kafka, and multi-region for a system serving modest traffic, they reveal that they don't understand the *costs* of those techniques (operational complexity, lost joins and transactions from sharding, distributed-systems difficulty from microservices, the expense and complexity of multi-region) or that those costs are only justified at scales the system won't reach. Every one of those techniques is a large, often irreversible commitment that should be adopted only when the numbers demand it, and adopting them prematurely imports enormous cost for capacity that isn't needed — which is a real, expensive mistake that wastes engineering time and adds failure modes. A simpler design that meets the requirements ("one Postgres and a cache handles this for years; I'd revisit sharding at 10× growth") demonstrates *superior* judgment: it shows the candidate understands the costs, resists complexity for its own sake, and can identify when the simple thing suffices — which is exactly the cost-awareness that distinguishes strong engineers. This creates the "over-preparer's paradox": candidates who've studied hard are tempted to *display* their knowledge of advanced techniques by using them all, not realizing that restraint scores higher than sophistication, and that the ability to say "we don't need that yet, here's why" is a more impressive signal than the ability to construct an elaborate architecture. The interview rewards proposing the simplest design that meets the requirements and justifying complexity only when the estimation demands it.
3. Why is silence the most damaging behaviour, and how does it interact with the remote setting? Because the interviewer can only evaluate what you say and do, and a design interview grades your *reasoning process*, not just your final answer — so a candidate thinking brilliantly but silently gives the interviewer nothing to score, and the natural interpretation of silence is that the candidate is stuck, lost, or has run out of ideas. The whole value you provide in the interview is the visible demonstration of how you think: how you scope, estimate, weigh trade-offs, handle failure, and reason under uncertainty — and all of that is invisible if you don't narrate it. Even correct conclusions score poorly if the reasoning that produced them isn't articulated, because the interviewer can't distinguish sound reasoning from a lucky guess or a memorized answer. This is amplified in the remote setting, which most interviews now use: in person, an interviewer can see you thinking — your expression, your gestures at the whiteboard, your evident engagement — so brief silences are read as thought; but on a video call, a silent candidate is a frozen screen with no voice, which reads unambiguously as being stuck or disengaged, and the interviewer has no way to tell the difference between productive thinking and being lost. The fix is to narrate continuously — think out loud, explain each decision as you make it, and *especially* speak when you're stuck ("I'm weighing two options here...") so the interviewer sees your reasoning process even in difficulty. Constant communication isn't just polite; it's the mechanism by which your competence becomes visible and therefore gradeable, which is why its absence is the single most damaging behaviour regardless of how good your underlying thinking is.
4. Why is "no trade-offs / reciting components" called the mid-level ceiling? Because it's the specific behaviour that prevents a candidate from being rated above mid-level, no matter how much they know. A candidate who can name all the right components and even configure them correctly — "I'll use a cache with cache-aside and a 5-minute TTL, a sharded database, and Kafka for events" — but presents each as simply *the* choice, without articulating what it costs, what the alternative was, or why it fits the requirements, has demonstrated *knowledge* but not *judgment*. They've shown they know the tools; they haven't shown they understand the decisions. Senior-level assessment specifically looks for trade-off reasoning — "I chose X, which costs us Y, over the alternative W, because the requirement is Z" — because that's the evidence of engineering judgment: understanding that every choice gives something up, knowing the alternatives, and deciding deliberately against real constraints. Without it, the interviewer sees someone who can recite the standard architecture but can't reason about *why* it's right or when it would be wrong, which caps them at mid-level regardless of the breadth of components they can name. This is why it's the single most common depth failure and the clearest ceiling: many candidates prepare by learning *what* components to use for each problem (which gets them to mid-level competence) but never practice articulating the trade-offs (which is what breaks through to senior). The fix is to make the trade-off sentence reflexive — for every decision, append "which costs us Y but gains Z, chosen over W" — so that reasoning, not just recitation, becomes the default mode of presenting every choice.
5. If you could only remember five of the 25 mistakes to avoid, which and why? **Requirements first** (never jump to a solution) — because designing before understanding the problem is the most common early failure, signals inexperience, and risks building the wrong system since the non-functional requirements drive the whole architecture. **State trade-offs** (don't just recite components) — because trade-off reasoning is the single biggest differentiator between mid and senior, and its absence is the mid-level ceiling; presenting choices without their costs demonstrates knowledge but not judgment. **Narrate constantly** (never go silent) — because the interviewer grades your reasoning process and can only evaluate what you say; silence is the most damaging behaviour, especially remotely, because it makes your competence invisible and reads as being stuck. **Handle failure** (answer "what if it fails?" for every component) — because everything fails at scale, failure handling is a heavily-weighted dimension, and only-the-happy-path designs signal inexperience; it's also the most common follow-up question, so being unprepared for it costs points repeatedly. **Start simple, don't over-engineer** — because premature complexity (sharding, microservices, multi-region for a small system) signals *poor* judgment rather than sophistication, and the over-preparer's paradox catches exactly the well-studied candidates; restraint and matching complexity to requirements is what senior judgment looks like. These five are chosen because they cause the most failures and span the framework's critical points: they cover the opening (requirements), the reasoning (trade-offs), the delivery (narration), the technical depth (failure), and the judgment (simplicity) — hitting all of them reliably clears the bar, while missing any one of them is a common and avoidable way to fail regardless of how much you know.

Further reading