Topics
System Design

How to actually approach a system design interview

A framework for the interview everyone dreads — and why it's testing something other than what you think.

The system design interview has a reputation for being the scariest round, and I understand why. There's no single right answer. There's a blank whiteboard, an enormous open-ended prompt — "design Twitter," "design a ride-sharing service" — and forty-five minutes to fill with something coherent. It feels like a test you can fail in a thousand ways.

But after sitting on both sides of these, I can tell you the fear is mostly misplaced. System design interviews are not testing whether you've memorized the architecture of a famous app. They're testing how you think when the problem is too big to hold in your head all at once — which, incidentally, is the actual job. The whole point is to watch you take ambiguity and impose structure on it, out loud, while making sensible tradeoffs.

Here's how to do that reliably.

What they're really evaluating

Before the framework, internalize what the interviewer is actually grading, because it changes how you spend your time.

They want to see whether you can scope a vague problem, whether you reason about tradeoffs instead of reciting "best practices," whether you can estimate scale and let that drive your decisions, and whether you can communicate a design clearly enough that someone else could build it. Notice what's not on that list: knowing the one correct architecture. There usually isn't one. A thoughtful design with clearly-stated tradeoffs beats a "perfect" design you can't justify every time.

The most common way to fail is not ignorance. It's silence and disorganization — jumping straight to a database schema, going quiet for long stretches, or building something wildly over-engineered for the actual requirements. The framework below exists to keep you out of all three traps.

The framework

Treat every system design interview as the same five moves, in order. Having a repeatable structure is half the battle, because it means you're never staring at the blank board wondering what to do next.

1. Clarify the requirements and scope. Do not start designing. Start asking questions. What exactly are we building? Who uses it and how? What are the core features we must support, and what's explicitly out of scope? An interviewer says "design Twitter," but they don't mean all of Twitter — they mean two or three core features. Pin those down. "So the core is: users can post short messages, follow others, and see a feed of people they follow. Should we handle things like search or notifications, or focus on the core first?" This single habit signals more seniority than almost anything else you'll do, because scoping before building is exactly what good engineers do on real work.

2. Estimate the scale. Numbers drive every interesting decision, so get some on the board early. How many users? How many requests per second? How much data per day? You don't need precision — you need order of magnitude. If a system handles 500 million tweets a day, that's roughly 6,000 writes per second on average, with peaks much higher, and storage that climbs into terabytes fast. Those numbers are what justify caching, sharding, and replication later. Without them, every architectural choice is arbitrary. With them, your design has a reason behind every box.

3. Sketch the high-level design. Now draw the big picture: clients, a load balancer, application servers, databases, caches, maybe a queue. Keep it coarse. Walk the interviewer through the path of a single request from end to end before you zoom in anywhere. You're establishing the skeleton everyone can agree on before you start arguing about any one bone.

4. Go deep on a few components. You can't deep-dive everything in forty-five minutes, and trying to is a mistake. Pick the two or three pieces that matter most for this problem and dig in. For a feed system, that's how you generate and store the timeline. For a URL shortener, it's how you generate unique keys and where you store the mappings. Let the interviewer steer here — if they push on a specific component, that's a hint about what they want to see. Show how the data is modeled, how the component scales, and where it might break.

5. Find the bottlenecks and discuss tradeoffs. This is where strong candidates separate themselves. Proactively identify where your design strains under load and talk through how you'd address it. Single database becoming a write bottleneck? Discuss sharding and its costs. Reads dominating? Add a cache and talk through invalidation. Every solution introduces a new tradeoff, and naming those tradeoffs out loud — "this gives us speed but adds eventual-consistency complexity" — is exactly the senior judgment they're listening for.

A quick worked example: a URL shortener

Let me run the framework on a classic, briefly, so you can see the shape of it.

Scope. We need to take a long URL and return a short one, and redirect from the short URL back to the original. Clarify: how short do the codes need to be? Do links expire? Do we need analytics on clicks? Say the interviewer wants the core: shorten, redirect, and links don't expire.

Scale. Suppose 100 million new URLs a month and a read-heavy workload — far more redirects than creations, maybe 100 reads for every write. That read-heavy ratio is the most important fact we'll uncover, and it should shape everything.

High-level design. Clients hit a load balancer, which routes to application servers. Writes go to a service that generates a unique short code and stores the mapping. Reads — the redirects — look up the code and return the original URL. Because reads dominate, a cache sits in front of the database to serve the hottest links from memory.

Deep dive: generating the code. The interesting problem is producing short, unique keys. One clean approach is to maintain a global counter and encode each new integer ID in base62 (the 62 alphanumeric characters), which gives you billions of short codes in just six or seven characters. We discuss the tradeoff: a single counter is a potential bottleneck, so we might hand out ID ranges to each server in batches so they can generate codes independently.

Bottlenecks. The database read path is the pressure point given our 100:1 read ratio, which is exactly why the cache earns its place — most redirects never touch the database at all. We'd also replicate the database for read scaling and durability.

That's a complete, defensible answer in a few minutes, and notice it never required a stroke of genius. It required structure and a willingness to reason about tradeoffs out loud.

The skill underneath the skill

Here's what took me too long to understand, both as a candidate and an interviewer: system design interviews are a communication exercise wearing a technical costume.

The candidates who do well aren't necessarily the ones with the deepest infrastructure knowledge. They're the ones who can take a sprawling problem, narrate a clear path through it, and bring the interviewer along every step. They think out loud. They make their assumptions explicit. They drive the conversation forward instead of waiting to be rescued. A silent genius covering the board in brilliant boxes scores worse than a clear communicator with a simpler design, because the interviewer can only evaluate what they can follow.

So practice the narration as much as the content. Say the tradeoffs out loud. Explain why before you draw what. The technical knowledge gets you in the room; the ability to walk someone through your reasoning is what actually gets you the offer.

That gap — between knowing the design and being able to talk through it under pressure — is the one almost nobody trains. It's exactly the gap a real spoken practice run is built to close. Knowing how to design the system and being able to explain it out loud, calmly, while someone watches, are two different skills. Interviews only reward the second one.