A Repeatable Approach
A framework for any design problem or interview: clarify functional and non-functional requirements, estimate scale, sketch a high-level design, deep-dive the hard parts, then find the bottlenecks.
On this page
System design is where every idea in this path meets scale. It's also the format of the dreaded "design a URL shortener" interview and the everyday reality of any real design review. What separates a strong designer from a flailing one isn't memorizing architectures - it's a repeatable approach that turns a vague, open-ended prompt into a structured conversation. The single biggest mistake is jumping straight to boxes-and-arrows before you know what you're building or how big it is.
The five-step approach
Whether in an interview or a real design doc, work through these in order. Resist the urge to skip ahead.
- Clarify requirements - both functional (what it does) and non-functional (how well). Never design in a vacuum; the requirements shape everything.
- Estimate scale - back-of-the-envelope numbers for traffic, storage, and bandwidth (next lesson). Scale is what turns "a database" into "a sharded, cached, replicated database."
- High-level design - the major components and how data flows between them. Boxes and arrows, kept simple.
- Deep-dive the hard parts - pick the one or two genuinely difficult components and go deep (the data model, the caching strategy, the sharding scheme).
- Identify bottlenecks and trade-offs - where does this design strain, and what would you do about it? This is where seniority shows.
Step 1: requirements are the whole game
The most common failure is designing the wrong system because you never asked what it needed to do. Split requirements into two kinds:
- Functional - the features. For a URL shortener: shorten a long URL, redirect a short URL to the original, maybe custom aliases and analytics. Pin these down; ask "is X in scope?"
- Non-functional - the qualities (the -ilities from the last module). How many users? Read-heavy or write-heavy? What latency? How available (99.9%? 99.99%?)? Consistency requirements? These drive the entire architecture - a system for 1,000 users and one for 1 billion are different designs.
Asking sharp non-functional questions early ("what's the read-to-write ratio? what availability do we need?") signals senior thinking and prevents you from over- or under-building.
Steps 3-5: design, deepen, then critique
With requirements and scale in hand, sketch the high-level design - client, load balancer, application servers, database, cache, queue - and the flow of a key request through them. Keep it simple; you'll refine.
Then deep-dive the parts that are actually hard for this problem (a URL shortener's interesting parts are the key-generation scheme and the read-path caching, not the load balancer). Finally, identify bottlenecks - "the database read path is the hot spot; here's how I'd cache and replicate it" - and name the trade-offs you made. There is no perfect design, only trade-offs; articulating them ("I chose availability over strong consistency here because a stale redirect is harmless") is exactly the judgment this whole path has built toward.
Don't jump to a solution before requirements and scale
The instinct - especially under interview pressure - is to start drawing a familiar architecture immediately. Resist it. A design only makes sense relative to its requirements and scale: caching, sharding, and queues are answers to specific pressures, and if you don't know the pressures, you're cargo-culting. Spend the first several minutes on requirements and estimation. A design grounded in 'we have 10K writes/sec and 100:1 reads' is defensible; the same boxes drawn cold are not.
A good building architect never opens with blueprints. They first ask the client what the building is FOR (a family home? a hospital? functional requirements), then how many people, what budget, what climate, what codes (non-functional constraints). Only then do they sketch a rough massing (high-level design), detail the hard parts like the foundation for the local soil (deep dive), and point out the trade-offs ('this open plan gains light but costs heating efficiency'). An architect who slaps down a generic blueprint before understanding the brief builds the wrong building beautifully. System design is identical: understand the brief (requirements + scale) before you draw a single box, and always surface the trade-offs you're making.
You're asked to 'design a system to store and serve user profile pictures.' Before drawing anything, list the functional and non-functional questions you'd ask, and explain how two different answers to a non-functional question would lead to genuinely different designs.
What's the correct first move when approaching a system design problem?
Key takeaways
- Use a repeatable approach: clarify requirements, estimate scale, sketch a high-level design, deep-dive the hard parts, then identify bottlenecks and trade-offs.
- Requirements are the whole game - split into functional (what it does) and non-functional (scale, latency, availability, consistency), which drive the architecture.
- Non-functional requirements turn 'a database' into a sharded, cached, replicated one; asking sharp scale/availability questions early signals senior thinking.
- Deep-dive only the parts genuinely hard for this problem, and keep the high-level design simple.
- There's no perfect design, only trade-offs - articulating them ('availability over consistency here because a stale value is harmless') is where seniority shows.