| Users / Load | 100 Users | 10K Users | 1M Users | 100M Users |
|---|---|---|---|---|
| Message Rate | ~100 msgs/sec | ~10,000 msgs/sec | ~1,000,000 msgs/sec | ~100,000,000 msgs/sec |
| Queue Size | Small (few 100s) | Medium (10K-100K) | Large (millions) | Very Large (billions) |
| Number of Producers | 1-5 | 50-100 | Thousands | Hundreds of thousands |
| Number of Consumers | 1-5 | 50-100 | Thousands | Hundreds of thousands |
| Throughput per Server | 1K-5K msgs/sec | Scale out with ~10 servers | Hundreds of servers | Thousands of servers or distributed clusters |
| Latency | Low (ms) | Moderate (tens ms) | Higher (hundreds ms) | Depends on partitioning and geo-distribution |
Producer-consumer pattern in HLD - Scalability & System Analysis
The first bottleneck is usually the message queue system. At low scale, a single queue server can handle all messages. As load grows, the queue's throughput and storage limits are reached first because it must store and deliver messages reliably.
Also, the consumer processing speed can become a bottleneck if consumers cannot keep up with the message rate, causing queue buildup and increased latency.
- Horizontal scaling: Add more queue servers and partition messages across them (sharding). Add more consumer instances to process messages in parallel.
- Partitioning: Use multiple queues or topics to split load by message type or key, reducing contention.
- Caching: Not typical for queues, but consumers can cache results to reduce repeated work.
- Load balancing: Distribute producers and consumers evenly across servers.
- Backpressure: Implement flow control so producers slow down when consumers lag.
- Durability tuning: Adjust persistence settings to balance speed and reliability.
- Use distributed messaging systems: Kafka, RabbitMQ clusters, or cloud-managed queues that scale automatically.
Assuming 10,000 messages per second at medium scale:
- Each message size: ~1 KB -> 10 MB/s data throughput
- Network bandwidth: 1 Gbps (~125 MB/s) can handle this comfortably
- Storage: For 1 hour retention, 10,000 msgs/sec * 3600 sec * 1 KB = ~36 GB storage needed
- Server capacity: One queue server handles ~5,000 msgs/sec, so 2-3 servers needed
- Consumer servers depend on processing complexity; assume 1 consumer per 1,000 msgs/sec -> 10 consumers
Start by explaining the basic producer-consumer flow. Then discuss how load increases affect the queue and consumers. Identify the bottleneck clearly. Propose scaling solutions step-by-step: horizontal scaling, partitioning, and backpressure. Use real numbers to show understanding. Finally, mention trade-offs like latency vs durability.
Your message queue handles 1,000 messages per second. Traffic grows 10x to 10,000 messages per second. What do you do first and why?
Answer: The first step is to horizontally scale the message queue by adding more queue servers or partitions to distribute the load. This prevents the queue from becoming a bottleneck. Also, increase the number of consumers to process messages faster and avoid backlog.
Practice
producer-consumer pattern in system design?Solution
Step 1: Understand the roles of producer and consumer
The producer creates tasks, and the consumer processes them separately.Step 2: Recognize the use of a queue
A queue buffers tasks to handle differences in speed between producing and consuming.Final Answer:
To separate task creation from task processing using a queue -> Option BQuick Check:
Producer-consumer = separate creation and processing [OK]
- Thinking producer and consumer do the same work
- Ignoring the role of the queue
- Assuming tasks are processed immediately without buffering
Solution
Step 1: Identify the flow of tasks
Tasks are created by the producer first.Step 2: Understand the buffering role
Tasks go into a queue before being processed by the consumer.Final Answer:
Producer -> Queue -> Consumer -> Option CQuick Check:
Task flow = Producer to Queue to Consumer [OK]
- Mixing the order of producer and consumer
- Placing queue after consumer
- Ignoring the queue as a middle step
Solution
Step 1: Compare producer and consumer speeds
Producer adds 5 tasks/sec, consumer processes 3 tasks/sec.Step 2: Analyze queue behavior
Since producer is faster, tasks accumulate, making the queue grow over time.Final Answer:
The queue will grow indefinitely -> Option AQuick Check:
Producer > Consumer speed = queue grows [OK]
- Assuming queue size stays constant
- Thinking consumer speed controls queue size alone
- Ignoring continuous task addition
Solution
Step 1: Understand fixed-size queue limits
The queue can hold only 10 tasks at a time.Step 2: Analyze producer behavior without checks
Producer keeps adding tasks even if queue is full, causing overflow.Final Answer:
Queue overflow causing task loss or system crash -> Option DQuick Check:
Fixed queue + unchecked producer = overflow [OK]
- Assuming queue grows automatically
- Thinking consumer stops when queue is full
- Believing producer slows down without control
Solution
Step 1: Identify system needs for spikes
System must handle sudden high message volume without data loss.Step 2: Choose scalable design
A dynamic queue size and multiple consumers allow flexible processing and prevent backlog.Final Answer:
Use a scalable queue with dynamic size and multiple consumers -> Option AQuick Check:
Scalable queue + multiple consumers = handle spikes [OK]
- Trying to limit producer speed strictly
- Removing queue causing lost buffering
- Using single consumer causing bottlenecks
Ready to prove it?
Pass the test and this pattern moves unknown
