Events and messaging

3 min read ·

Dead Letter Queue: Who Notices the Work That Did Not Finish?

A message was moved aside. That protected the queue, but it did not finish the customer's order.

An order reaches the fulfilment queue, but the warehouse cannot process it because the message contains data this version of the service does not understand. Retrying fails. So does the next retry. Keeping that loop running can consume capacity and delay every order behind it.

A Dead Letter Queue, or DLQ, sets aside messages that normal processing cannot complete. Calling this “error handling” can be misleading. We have stopped a bad message from blocking other work. We have not solved the customer's problem.

Temporary failure or permanently invalid input?

If a database is briefly unavailable, retrying later may succeed. Those failures need limited retries and an appropriate delay. But if a required field is missing or the consumer does not understand the event schema, repeating the same request is unlikely to help.

After a configured number of attempts, the system may park the message in a separate queue, topic or storage location, along with enough context to investigate. The original operation ID must remain traceable.

The error moved; the business obligation did not

A customer gains little from hearing that eighteen records are in a DLQ. They need the order fulfilled or an explanation of the delay. Someone must own the backlog: detect failures, find causes and decide whether to replay, repair manually or close the operation another way.

The age of the oldest failed operation and the number of affected customer journeys can be more useful than queue depth alone. A failed background report and a stuck payment confirmation require very different responses.

Why replay-all is dangerous

Once the bug is fixed, it can be tempting to push every dead-letter message back into the main queue. But the business state may have changed. The order might have been cancelled, stock allocated elsewhere or money refunded by support.

Replay must respect idempotency, current entity state and message versions. Sometimes the right recovery is a new compensating business action rather than blindly executing an old command again.

Dead-letter storage can also contain personal or sensitive data. Access and retention policies should not disappear just because processing failed.

When the mechanism adds no value

A small synchronous application without messaging usually does not need a DLQ. If the caller must know immediately whether a command succeeded, moving the failure aside may hide it instead of resolving it.

A DLQ is useful when it lets healthy work continue. But every parked message still needs an owner, a decision and a way to account for the customer's unfinished business.