Bird
Raised Fist0

How to Present Trade-offs and Justify Design Decisions to Interviewers

HLDmediumInterview freq: high
Choose your preparation mode4 modes available
🏗️
How to Present Trade-offs and Justify Design Decisions to Interviewers
Master articulating design trade-offs with scale-driven justifications in system design interviews
mediumSystem Design Interview ApproachFreq: high
Prerequisites:System Design FundamentalsCAP Theorem
⚙️
Functional Requirements
  • Clearly articulate functional requirements and constraints of the system under design
  • Identify and explain key non-functional requirements with concrete scale numbers
  • Ask clarifying questions that reveal deeper understanding of system scope and scale
  • Present multiple design alternatives and justify the chosen approach with trade-offs
  • Explain failure modes and mitigation strategies for the proposed design
📊
Non-Functional Requirements
  • Support at least 2 billion daily active users (DAU)
  • Handle peak write throughput of approximately 925,000 writes per second
  • Ensure 99.99% system availability and durability
  • Maintain 100ms P99 latency for critical read and write operations
  • Design for horizontal scalability and fault tolerance
❓
Clarifying Questions to Ask
  • What is the expected read-to-write ratio under peak load?
  • What is the data retention period and archival requirements?
  • Are there any consistency guarantees required (strong, eventual, causal)?
  • What are the failure scenarios we must tolerate (node failures, network partitions)?
  • Is the system expected to support multi-region deployment or geo-replication?
  • What are the SLAs for latency and availability under normal and peak conditions?
Out of Scope
✗ Detailed low-level implementation or code-level optimizations
✗ Specific UI/UX design considerations
✗ Security and compliance beyond basic authentication and authorization
✗ Third-party integrations or external system dependencies
📌
Assumptions
  • 2 billion daily active users (DAU)
  • Each user generates 40 messages per day on average
  • Average message size is 100 bytes
  • Data retention period is 30 days
⚡
QPS Calculation
write qps2,000,000,000 × 40 / 86,400 ≈ 925,926 writes/sec
peak write qpsAssuming 2× peak factor: 925,926 × 2 ≈ 1,851,852 writes/sec
read qpsAssuming 10 reads per write: 925,926 × 10 ≈ 9,259,260 reads/sec
💾
Storage Estimate
daily storage2,000,000,000 × 40 × 100 bytes = 8,000,000,000,000 bytes ≈ 7.28 TB/day
retention storage7.28 TB × 30 days = 218.4 TB
with replicationAssuming 3x replication: 218.4 TB × 3 = 655.2 TB total storage
🖥️
Server Estimate
write pathUsing Cassandra nodes with 10,000 writes/sec capacity → 1,851,852 / 10,000 ≈ 186 nodes
read pathUsing Redis clusters with 50,000 reads/sec capacity → 9,259,260 / 50,000 ≈ 186 nodes
🏗️
Architecture Diagram
Architecture Diagram
          +----------------+
          |   Client Apps  |
          +-------+--------+
                  |
                  v
          +-------+--------+
          |  API Gateway   |
          +-------+--------+
                  |
          +-------+--------+
          |  Load Balancer |
          +-------+--------+
                 / \
                v   v
 +-------+--------+  +------+-------+
 | Write Service  |  | Read Service |
 +-------+--------+  +------+-------+
         |                  |
         v                  v
 +-------+--------+  +------+-------+
 |  Kafka Cluster |  | Redis Cluster|
 +-------+--------+  +------+-------+
         |                  |
         v                  v
 +-------+--------+  +--------------+
 | Cassandra DB   |  |  Cache Layer |
 +----------------+  +--------------+
🧩
Components
API Gateway
Entry point for all client requests, handles authentication, rate limiting, and routing
Why thisEnvoy proxy supports high throughput with built-in observability and dynamic routing
Why notNginx lacks native service discovery and dynamic configuration at scale
Kafka Cluster
Durable, distributed message queue for write buffering and asynchronous processing
Why thisKafka provides partitioned logs with high throughput and strong ordering guarantees
Why notRabbitMQ does not scale linearly beyond 100K msg/sec and lacks native partitioning
Cassandra DB
Primary storage for messages with horizontal scalability and tunable consistency
Why thisCassandra’s ring architecture supports linear write scalability and multi-datacenter replication
Why notPostgreSQL requires manual sharding and cannot handle 1.8M writes/sec without bottlenecks
Redis Cluster
Caching layer for hot data to reduce read latency and offload Cassandra
Why thisRedis Cluster supports automatic sharding and sub-millisecond P99 read latency
Why notMemcached lacks persistence and cluster management features needed at scale
Write Service
Processes incoming writes, validates, and publishes to Kafka for durability
Why thisStateless microservice design enables horizontal scaling and fault isolation
Why notMonolithic write processing causes scaling bottlenecks and slower deployments
Read Service
Serves read requests by querying Redis cache first, then Cassandra fallback
Why thisCache-aside pattern reduces load on Cassandra and meets 100ms P99 latency SLA
Why notDirect Cassandra reads cause higher latency and increased load under peak
Load Balancer
Distributes incoming API requests evenly across write and read service instances
Why thisAWS ALB supports path-based routing and health checks for high availability
Why notDNS round-robin lacks health awareness and fine-grained routing control
🔄
Data Flow
1
Client Apps → API Gateway
Send write/read requests
Clients authenticate and send requests via HTTPS
2
API Gateway → Load Balancer
Route requests to appropriate service
Routes writes to Write Service, reads to Read Service
3
Write Service → Kafka Cluster
Publish validated messages
Ensures durability and decouples ingestion from storage
4
Kafka Cluster → Cassandra DB
Consume and persist messages
Cassandra stores messages with tunable consistency
5
Read Service → Redis Cluster
Query cache for requested data
Cache hit returns data with low latency

Practice

(1/5)
1. A system must handle 1 million writes per second and fan-out to millions of users asynchronously. Which component best handles decoupling write load from delivery?
easy
A. Use direct HTTP calls from sender to all receivers to guarantee delivery order
B. Use a relational database with sharded writes to handle all writes and fan-out synchronously
C. Use an in-memory cache like Redis to store all messages and fan-out immediately
D. Use a distributed message queue like Kafka to buffer writes and enable asynchronous fan-out

Solution

  1. Step 1: Identify the need for decoupling writes from fan-out

    Handling 1 million writes per second with synchronous fan-out is not feasible on a single machine or direct calls.
  2. Step 2: Evaluate components for asynchronous buffering

    Kafka provides durable, partitioned logs that buffer writes and allow scalable asynchronous delivery. Relational DBs can't handle this write load synchronously. Redis lacks durability guarantees for this scale. Direct HTTP calls block and don't scale.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Kafka buffers writes asynchronously, enabling high write throughput [check]
Hint: Use durable queues to decouple high write load [check]
Common Mistakes:
2. For delivering real-time location updates to mobile clients, which approach is better considering intermittent mobile network connectivity and battery constraints?
medium
A. Use WebSocket connections with automatic reconnection and heartbeat pings
B. Use persistent gRPC streaming connections to push updates continuously
C. Use HTTP long polling to simulate real-time updates
D. Use periodic client polling every few seconds to fetch updates

Solution

  1. Step 1: Evaluate persistent connection options

    gRPC streaming is efficient but less supported on mobile platforms and can drain battery.
  2. Step 2: Compare WebSocket and polling

    WebSocket supports bidirectional communication with reconnection and heartbeats, balancing real-time and battery use better than polling.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    WebSocket balances real-time updates and mobile constraints [check]
Hint: WebSocket with reconnection beats gRPC streaming on mobile [check]
Common Mistakes:
3. If the Market Data Feed component crashes and stops publishing updates, what is the exact failure observed by external clients subscribing to real-time stock prices?
medium
A. Clients receive stale prices indefinitely with no indication of failure
B. Clients receive partial updates but with delayed timestamps causing confusion
C. Clients receive an error message and automatic reconnection attempts begin
D. Clients continue receiving cached data from the Matching Engine without updates

Solution

  1. Step 1: Understand Market Data Feed failure impact

    When Market Data Feed crashes, it stops pushing updates; clients detect connection loss and receive error events triggering reconnection.
  2. Step 2: Eliminate other options

    Clients receive stale prices indefinitely with no indication of failure is wrong because clients detect connection loss; Clients receive partial updates but with delayed timestamps causing confusion is wrong because partial updates don't occur without feed; Clients continue receiving cached data from the Matching Engine without updates is wrong because Matching Engine doesn't serve cached market data.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Feed crash -> clients get error + reconnect attempts [check]
Hint: Feed crash triggers client error and reconnect [check]
Common Mistakes:
4. At 10x scale, which component in the CDN architecture for adaptive bitrate HLS streaming is most likely to fail first, and why?
hard
A. Origin servers, because they cannot handle the increased number of segment requests
B. Edge cache nodes, because their limited storage causes frequent cache evictions and increased origin fetches
C. Load balancers, because they become bottlenecks distributing requests to edge nodes
D. Client players, because they cannot handle rapid bitrate switching at scale

Solution

  1. Step 1: Identify bottleneck at 10x scale

    Edge cache nodes have limited storage and memory; increased users cause cache thrashing and more origin fetches, increasing latency and load.
  2. Step 2: Evaluate other components

    Origin servers scale with CDN design; load balancers are horizontally scalable; client players are distributed and not a system bottleneck.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Edge cache storage limits cause cache thrashing first at scale [check]
Hint: Edge cache storage limits cause thrashing before origin overload [check]
Common Mistakes:
5. At 10x scale, which component in the job portal system is most likely to become the first bottleneck, and why?
hard
A. WebSocket servers maintaining live candidate-job chat sessions, due to stateful connections limiting horizontal scaling
B. Relational database storing user profiles, due to complex joins and ACID constraints
C. Search index cluster, due to increased indexing latency from frequent job postings
D. Message queue cluster, due to partition limits causing uneven load distribution

Solution

  1. Step 1: Identify stateful components limiting scale

    WebSocket servers hold persistent connections bound to server memory, limiting resharding.
  2. Step 2: Compare other components

    Relational DB (A) can be scaled with sharding; search cluster (C) scales horizontally; message queues (D) can add partitions. Stateful WebSocket servers (B) face connection stickiness and memory limits first.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Stateful WebSocket connections -> scaling bottleneck at 10x load [check]
Hint: Stateful WebSocket servers limit horizontal scaling first [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard