Design Process
Design is a sequence of questions
When you get a task such as “design a URL shortener,” it is tempting to immediately start drawing servers, databases, and caches. That is a dangerous habit: you can build a beautiful diagram for a problem nobody actually asked you to solve.
A good process moves from general to specific. First, clarify the system goal, then capture the requirements, and only after that choose components that help satisfy those requirements.
Problem
↓
Requirements
↓
Constraints and scale
↓
High-level design
↓
Critical components
↓
Check bottlenecks and trade-offs
1. Clarify the scope
Before designing, agree on what is actually part of the system. For a URL shortener, for example, creating a short link and redirecting through it are core scenarios, while advanced advertising analytics may be completely outside the current task.
Scope protects you from endless design. We are not trying to solve every possible future problem in advance; we are building a system for a clear set of requirements.
2. Capture requirements and constraints
Next, separate what the system does from how well it must do it. In the following topics, we will cover functional and non-functional requirements separately. For now, the key idea is that they become the criteria used to evaluate the architecture later.
3. Draw the smallest useful design
A high-level design answers this question: which major parts participate in handling a request, and how does data move between them? On the first pass, there should be very few details.
Client → API → Application → Storage
If the diagram already explains the main request path, it is enough to begin with. Replicas, queues, caches, and other elements should be added when there is a reason for them to exist.
4. Go deeper into critical areas
Not every part of a system is equally important. In one system, storage may be the main risk; in another, it may be a huge number of reads; in a third, long-running request processing. That is why, after the high-level design, it is useful to choose a few of the most important areas and work through those specifically.
5. Test the design against growth and failure
The last pass is to mentally “break” your own architecture. What happens if the number of requests grows? If one component stops responding? If data grows faster than expected? These questions reveal weak points before the system reaches production.