Understanding large-scale system architecture
Why do companies do system design interviews? What are they looking for?
This round often determines your level and assesses your ability to design large-scale, scalable, reliable, and maintainable software systems.
Can you break down a complex problem? Companies want to see if you can decompose a product or service into individual components like APIs, databases, caches, queues, etc.
Can you make trade-offs? Choosing between SQL vs. NoSQL, or consistency vs. availability (CAP theorem).
Can your system handle scale? Think millions of users, high throughput, low latency.
Do you understand bottlenecks and how to mitigate them? Load balancing, partitioning, replication, etc.
Can you communicate your design clearly? Explaining concepts to stakeholders (PMs, other engineers) is crucial.
Are you open to feedback and iteration? It's not just about having a perfect design — it's about refining it collaboratively.
Do you apply practical, not theoretical, knowledge? For example, designing a notification system that prioritizes user experience under high load.
Can you anticipate edge cases and failures? Handling server crashes, data loss, retries, rate limiting, etc.
Can you innovate under constraints? Budget limits, data consistency requirements, or tight latency SLAs.
How do you approach new or unfamiliar domains? They want to see structured thinking even if the domain is new to you.
In short: System design interviews test your ability to be a "tech lead" or senior engineer — someone who can design solutions that work at scale, are maintainable, and meet business goals.
Note: The bar is raising — sometimes junior and mid-level folks get asked these now.
What IS a system?
Objective: Understand the problem and what is being asked. Ask clarifying questions to make sure you know exactly what the system needs to do.
Action: If the problem is broad, narrow it down. For example, if you're asked to design a "social media platform," clarify things like: "Are we focusing on newsfeed? Messaging? Scaling?" etc.
In a system design interview, you don't ask "What are the functional requirements?" or "What are the non-functional requirements?" These are things you as the interviewee are expected to determine and clarify during the discussion.
Your job is to identify what the system needs to do (functional) and how well it needs to perform (non-functional) through your analysis and questions about the problem.
Functional requirements describe the core behaviors and features of a system — the "what".
Examples:
Non-functional requirements describe the quality attributes of the system — the "how well" or "under what constraints".
Examples:
You can't say "the system must be available 99.99% of the time" unless you know:
Functional: "Users can submit payments"
Non-functional: "Payments must process in <1 second with 99.9% success rate"
Without knowing the function (payment submission), the performance goal (1s) is meaningless.
In a system design interview, "back-of-the-envelope" estimates are canonically part of the clarifying phase.
"Before diving into design, let's estimate how much traffic we're dealing with..."
Once your estimates shape the problem size, you can reference them in your high-level design:
Objective: Start sketching the system's high-level architecture.
Action: Identify major components, how they interact, and how data flows. Consider the trade-offs between components (e.g., SQL vs. NoSQL databases). Also, bring up any assumptions you might be making.
Objective: Dive into individual components or subsystems of the architecture.
Action: Pick one or two critical parts of the system and design them in detail. For example, if you're designing a messaging system, you could focus on message storage, delivery guarantees, and scaling. Explain the protocols, APIs, and data models you would use.
Objective: Address scalability, availability, and reliability.
Action: Discuss how your system will scale horizontally and vertically. Consider potential bottlenecks (e.g., database, network, etc.), data sharding, caching strategies, load balancing, and failover strategies.
Objective: Discuss trade-offs in design decisions and how to mitigate potential bottlenecks.
Action: For instance, if you've chosen a certain database type, explain why you chose it and what trade-offs were involved (e.g., SQL vs. NoSQL). Also, talk about how you'd handle potential issues, such as system outages or data consistency challenges.
More Complex Examples: Discuss trade-offs like eventual consistency (social media likes - okay if delayed) vs. strong consistency (banking transactions - must be immediate), synchronous (user login - wait for response) vs. asynchronous processing (email notifications - send in background), or caching strategies (write-through vs. write-behind vs. cache-aside).
Objective: Summarize your system design and answer any final questions.
Action: Be prepared to summarize your system in 2-3 sentences and have thoughtful questions ready for the interviewer. Demonstrate your understanding by asking about potential edge cases, scaling considerations, or alternative approaches they might consider.
Don't just study these concepts theoretically! You must create tiny projects using these technologies. If you rely purely on academic knowledge, you'll fold when the interviewer presses for implementation details or tries to poke holes in your plan.
Real hands-on experience is what separates candidates who can talk the talk from those who can walk the walk.
Candidates who show they can walk, better yet run, are the ones who get the job.
Examples: PostgreSQL, MySQL, Microsoft SQL Server, Oracle
Key Features:
When to Use: You need complex queries and relationships (e.g. banking, ecommerce)
Types:
When to Use:
Redis, Memcached
Session storage, page caching, database query results
LRU, LFU, FIFO
Write-through, write-back, TTL
Hit/miss rate, eviction count, latency, memory usage
Examples: RabbitMQ, Amazon SQS, ActiveMQ
Messages are typically sent to a queue, where they are stored until consumed.
Each message is delivered to a single consumer (point-to-point).
Often supports features like message acknowledgments, retry, dead-letter queues, and priority queues.
Good for task queues, background job processing, and decoupling microservices.
Examples: Apache Kafka, Amazon Kinesis
Data is written to a topic, which acts as a durable, append-only log.
Each topic is split into partitions, which enable parallelism and scaling.
Multiple consumers can read from the same topic independently, enabling pub/sub and fan-out architectures.
Consumers track their position using an offset, allowing replay and fault recovery.
Excellent for event sourcing, real-time analytics, and data pipelines.
What it is: A messaging pattern where publishers emit messages to a topic, and multiple subscribers independently consume them.
Common Systems: Google Pub/Sub, Kafka, Redis Pub/Sub
Key Concepts: Fan-out, durable vs. ephemeral subscriptions, push vs. pull
Relation to Event Streaming: Kafka is a pub/sub system under the hood.
What it is: An append-only, immutable log shared across distributed nodes.
Example: Kafka is a distributed log.
Relation to Event Streaming: Event streaming platforms are distributed logs; used for replaying events, CDC (Change Data Capture), etc.
What it is: Systems that manage background jobs and retries
Examples: Celery
Relation to Message Brokers: Message brokers like RabbitMQ or SQS are often used as underlying transport.
What it is: A design style where services react to events instead of API calls
Key Concepts: Event producers, consumers, event store, eventual consistency
Relation to Messaging: Messaging systems are the core of EDA. Events flow through message brokers or streaming platforms, enabling services to react asynchronously to changes in the system. This decoupling allows for scalable, resilient architectures where services don't need to know about each other directly.
CAP Theorem states that in any distributed system, you can only guarantee two out of the following three properties at any given time:
Every read receives the most recent write or an error. All nodes see the same data at the same time.
Every request receives a non-error response, even if it's not the latest data. The system is always responsive.
The system continues to operate despite network failures or message delays between nodes.
You must tolerate partitions in a distributed system — network failures are inevitable. So, in reality, you are forced to choose between Consistency vs. Availability when a partition occurs.
A transaction is a sequence of one or more operations that are treated as a single, indivisible unit of work. Either all operations complete successfully, or none of them do.
Imagine transferring $100 from Account A to Account B:
If the system crashes after step 2, the transaction rolls back to prevent data loss.
A race condition occurs when two or more operations happen concurrently, and the final outcome depends on the non-deterministic timing or order of their execution.
Example: Two users withdraw from same account
User 1: Read balance: $100
User 2: Read balance: $100 (same time)
User 1: Withdraw $80 → Balance: $20
User 2: Withdraw $80 → Balance: $20 (overdraft!)
Expected: $100 - $80 = $20 (only one withdrawal)
Actual: Both withdraw $80, ending with -$60Solution: Use transactions with proper isolation levels, locks, or optimistic concurrency control.
A process is an independent program in execution. It has:
Think of it as: A fully isolated container running a program.
A thread is the smallest unit of execution within a process:
Think of threads as: Workers inside the same container doing different tasks but sharing tools.
In a system design interview, you typically define APIs after you understand the data models, but the process is iterative. Here's the breakdown:
"Let's define the core data models first so we know what entities the APIs need to interact with. Once we have a sense of the relationships and structure, we can define clean APIs around them."
That shows structured thinking and interviewers like it.
Sometimes defining an API leads you to adjust a model.
Example: Designing POST /checkout might make you realize you need a Cart or Transaction entity that wasn't in your initial model.
Why data models often come first:
Example: If you're designing a ride-sharing app:
You need to define models like User, Ride, Driver, Location before deciding on APIs like:
Define core data models / entities in the high level design portion of the interview.
High-Level Design (HLD): Key components, major interactions, core data models (at least basic entities), and rough API boundaries
Low-Level Design (LLD): Detailed schema, indexing, table structure, API request/response formats, protocol details, error handling
Can you steer the interviewer to your strengths? Yes — absolutely, and it's a smart move.
How to do it effectively:
If you're strong on storage design:
"We can briefly sketch the API layer, but I'd love to dive into how we model the data, choose the database, and handle writes under load."
Interviewers want signal, not a perfect system.
Driving the conversation where you're strongest is a great way to demonstrate value.
Just don't completely dodge weak areas — show awareness even if you keep it high level.
Key Principles:
Remember: The goal isn't to build a perfect system, but to show you can think through complex problems, make reasonable trade-offs, and communicate your approach effectively.
Practice these concepts with real projects, and you'll be well-prepared for system design interviews.