How the interviewer opens it
“Design a distributed message queue like RabbitMQ or SQS. Producers enqueue work for competing consumers, with acknowledgements, retries, and dead-letter queues.”
The prompt is vague on purpose. The first few minutes are yours: narrow it to the core features and agree on the numbers before you draw anything.
What to clarify first
- scale
- message size and retention
- read:write mix
- delivery and ordering
- consumer timing
- retries and dead letters
- latency
- durability and availability
- scope boundaries
The answers stay with the interviewer. In a SysRound round, Alex answers them as an interviewer would.
Scope of a strong answer
Core requirements
- Durably enqueue messages and deliver each message to one competing consumer at a time
- Support acknowledgements and visibility timeouts for recovering abandoned work
- Retry failed deliveries and move repeatedly failing messages to a dead-letter queue
- Create queues with retention, visibility timeout, and retry settings
Usually out of scope
- Strict FIFO ordering
- Publish-subscribe fanout
- Exactly-once execution of arbitrary consumer side effects
- Cross-region active-active operation
- Building the consumer application
What interviewers probe
- Visibility leases do not provide exactly-once processing
- The broker can coordinate delivery ownership, but it cannot atomically commit an arbitrary consumer side effect together with the acknowledgement. Slow consumers can keep running after their leases expire.
- Replicating queue state and reclaiming completed messages
- Payload replication alone is insufficient: leases, attempts, and acknowledgements must survive failover too. Competing consumers finish out of order, so a single consumed offset does not describe what can be deleted.
- Retry storms and lossless dead-letter transfer
- A broken dependency can make most messages fail together. Moving a message between independently replicated queues also creates a failure window where a naive delete-then-publish loses work.
- Hot queues, long polls, and bounded resource use
- Queue count is not a useful load-balancing unit when one queue carries 100,000 messages per second. Idle polling and slow consumers can also consume resources without increasing useful throughput.
Common mistakes
- Promising exactly-once business processing because the queue has acknowledgements.
- Using Redis list removal or in-memory visibility state as the entire durability design.
- Replicating enqueues but forgetting to replicate leases, retry counts, and acknowledgements.
- Treating competing-consumer completion as a single stream offset.
- Implementing DLQ transfer as delete-then-send or retrying poison messages without backoff.
- Ignoring hot logical queues, disk backlog growth, or the cost of empty polling.
The bar by level
- Senior (L5/E5)
- Defines durable commit points and failover behavior for all queue state, handles long-running consumers and ambiguous responses, gives a lossless DLQ-transfer protocol, and partitions hot queues with bounded polling and storage usage.
- Staff (L6+/E6+)
- Reasons through network partitions and stale leaders, recovery and compaction costs, online shard movement with outstanding receipts, and tenant isolation under retry storms. Quantifies capacity and durability trade-offs and distinguishes broker guarantees from what must be enforced at the consumer's side-effect boundary.