System design interviews can be intimidating, especially when you're asked to design a scalable, high-performing, and reliable system under time pressure.
These interviews test your ability to break down complex problems, design systems that meet specific requirements, and communicate your thought process effectively.
Here is a 7-step process that can help you do well in your system design interviews:
1 - Requirements Clarification
The first and most critical step is to clarify the system's functional and non-functional requirements. This ensures that you fully understand the problem you’re solving and helps avoid miscommunication later in the process.
Key Questions to Ask:
Functional Requirements: What are the core features of the system? For example, in a URL shortener, the ability to create, store, and retrieve short URLs is a core requirement.
Non-Functional Requirements: Ask about performance, scalability, availability, and reliability expectations. Does the system need to handle millions of users? Should it guarantee low latency?
Pro Tip:
Write down the requirements for both parties to refer back to during the discussion. For instance:
Functional: User authentication, real-time updates.
Non-Functional: Low latency (<100ms), 99.99% uptime.
2 - Capacity Estimation
Once the requirements are clear, estimate the system's capacity. This involves understanding the scale at which the system operates.
Typical Metrics to Estimate:
Number of Users: Total users and active users per second.
Traffic: How many requests per second (RPS) will the system handle?
Storage: How much data will the system store daily, monthly, or yearly?
Bandwidth: What is the expected data transfer rate between components?
Example:
If you’re designing a chat application:
Active users: 1M daily active users, 100K concurrent users.
Messages per second: Each user sends 1 message every 10 seconds → 10K messages/second.
Storage: Each message is 1KB → 864GB of messages per day.
3 - Create High-Level Design
Next, create a high-level architecture for the system. Start by breaking it into components and mapping out their interactions.
Steps:
Identify the major components: Client apps, load balancers, application servers, caching layers, databases, etc.
Create a simple block diagram to show how these components interact.
Focus on data flow: How does data travel through the system, from the user to storage and back?
Pro Tip:
Keep the diagram simple at first and add details incrementally as you refine the design.
4 - Database Design
A well-thought-out database design is crucial for most systems. The goal is to choose the right database type and schema to store and retrieve data efficiently.
Steps:
Choose the Database Type:
Relational (e.g., MySQL, PostgreSQL): For structured data with strict relationships.
NoSQL (e.g., MongoDB, Cassandra): For unstructured or semi-structured data, or for scalability.
Design the Schema:
Normalize or denormalize tables depending on query patterns.
Define primary and secondary indexes for faster lookups.
Example:
In a ride-sharing app, you might use:
Relational DB for user and ride data.
Geospatial indexing for fast location queries.
5 - Interface Design
After database design, focus on interfaces. Define how components interact, including APIs and communication protocols.
Steps:
Identify the APIs:
Example: For a video streaming service, APIs like
/upload
,/stream
, and/search
.
Choose the Communication Protocol:
REST: For simple, stateless interactions.
GraphQL: For flexible, client-defined data queries.
gRPC: For low-latency, high-performance interactions.
Define Data Contracts:
Specify request and response formats (e.g., JSON, Protobuf).
Why It’s Important:
Well-defined interfaces ensure seamless communication between components.
They act as a contract between services, reducing ambiguity during development.
6 - Scalability and Performance
To meet non-functional requirements like scalability and low latency, you need to address system performance.
Techniques to Consider:
Vertical Scaling: Add more resources (e.g., CPU, RAM) to existing servers.
Horizontal Scaling: Add more servers to handle increased traffic.
Caching:
Use in-memory stores like Redis or Memcached to reduce database load.
Cache frequently accessed data, such as user profiles or product catalogs.
Indexing and Denormalization:
Add indexes to speed up database queries.
Denormalize data to reduce complex joins.
CDNs:
Use Content Delivery Networks to serve static assets closer to users.
Why It’s Important:
Scalability ensures the system handles growth without degradation.
Optimizations reduce latency and improve the user experience.
7 - Reliability and Resiliency
Finally, address how your system handles failures to ensure reliability and resiliency.
Strategies:
Identify Single Points of Failure:
Use redundant load balancers, databases, and servers.
Replicate data across multiple availability zones or regions.
Resiliency Techniques:
Implement circuit breakers to prevent cascading failures.
Use retries with exponential backoff for transient errors.
Data Durability:
Use backups and snapshots for disaster recovery.
Ensure data replication and consistency across nodes.
Why It’s Important:
Reliability ensures high uptime and trustworthiness.
Resiliency minimizes the impact of failures, keeping the system operational.
Example:
In an e-commerce platform:
Use active-active replication for the database.
Deploy health checks for services with automatic failover mechanisms.
👉 So - which other tip will you add to the list?
Shoutout
Here are some interesting articles I’ve read recently:
The Silent Art of Comment Mastery by
Stop Using NULL. It's a Bad Practice by
50% faster delivery: Accelerate your projects by prototyping by
That’s it for today! ☀️
Enjoyed this issue of the newsletter?
Share with your friends and colleagues.
Good breakdown, Saurabh!
One addition:
Think in terms of read vs write scaling.
- Reads scale with caching and replication.
- Writes need partitioning and careful consistency trade-offs.
Thanks for the article.
Better to approach interviews with a step-by-step plan. And this is a great one!