Backend coding interview

Message Queue Consumer Coding Interview Problem

Idempotency & retriesMessagingHard

What this interview round tests

Every backend that uses Kafka, SQS, or RabbitMQ eventually asks the same interview question: your queue delivers at least once — what does your consumer do about it? This problem is that question as runnable code. A message can arrive twice, arrive out of order after a retry, or fail processing five times in a row, and the consumer must produce exactly-once effects anyway.

Interviewers reach for it because it separates candidates who have used a queue from candidates who have operated one. The mechanics under test — dedupe keys, retry budgets with backoff, and the dead-letter queue as a pressure valve — are the difference between a consumer that survives a bad deploy and one that grinds a poison message forever while the backlog grows. It is a staple follow-up in SDE2 loops wherever asynchronous processing appears.

The scenario

You are handed the consumer side of a messaging system: messages are pulled from a queue, processed into side effects, retried on failure, and parked in a DLQ when they exhaust their attempts. The pipeline exists end to end, and the test suite breaks it in every dimension.

Redelivered messages apply their effects twice, a failing message is retried instantly and forever instead of backing off, messages that should be dead-lettered keep circulating, and a retry that finally succeeds still leaves duplicate side effects behind. Your job is to make consumption at-least-once on the wire but exactly-once in effect.

What you’ll practice

  • At-least-once semantics: why redelivery is normal, not an error
  • Idempotent processing: keying effects by message identity so replays are no-ops
  • Retry policy: bounded attempts with exponential backoff, not hot loops
  • Dead-letter queues: parking poison messages without losing them
  • Ack/nack discipline: when a message leaves the queue, and when it must not
  • Ordering hazards: a retried message overtaking its successors safely

How to approach it

Start from the identity of a message, not its payload: processing must record "I have handled message X" atomically with X’s side effects, so a redelivery finds the record and returns without acting. If the record and the effect can be written separately, there is a crash window between them — walking that window is most of the problem.

Then make failure boring. Each attempt decrements a budget; each retry waits longer than the last; and when the budget hits zero the message moves to the DLQ with its error context instead of vanishing or recirculating. The tests simulate a poison message inside a healthy stream — the grading is whether the stream keeps flowing while the poison is quarantined.

The starter repository ships with a failing test suite and a bundled verify.sh. Reviewed reference solutions are part of Gronex Pro — this page stays spoiler-free on purpose.

Try it in a real repository

LeetCode teaches algorithms. Gronex teaches backend coding rounds with real repositories, failing tests, service logic, and production-style constraints. Open the brief and read the full problem — no signup required.

FAQ

Why can’t the queue just deliver each message exactly once?

Because the network can fail after processing but before the acknowledgement arrives — the broker cannot tell "processed but unacked" from "never processed", so it redelivers. Exactly-once is therefore a property your consumer builds with idempotency, not a setting a broker provides.

What is a dead-letter queue actually for?

It is the escape hatch for messages that will never succeed — malformed payloads, deleted entities, poison pills. Without one, a single bad message either blocks its stream or burns retries forever. Parking it with error context keeps throughput alive and preserves the evidence for debugging.

Do I need Kafka or RabbitMQ installed to practise this?

No. The repository models the queue, redeliveries, and failures in-process, so every duplicate and crash is deterministic, and the bundled test suite grades your consumer logic directly in Java, Python, or C++.

Related