How to introspect dead-letter queues in RabbitMQ

April 14, 20254 min readProduct

How to introspect dead-letter queues in RabbitMQ

Why you cannot "look" into a RabbitMQ queue?

It’s tempting to think of queues like databases: stores of messages you can browse, query, or peek into at will. But RabbitMQ doesn’t work that way. By design, RabbitMQ treats queues as strictly FIFO (First-In, First-Out) pipelines: once a message is in the queue, the only supported way to access it is by consuming it from the front. There's no API to peek at arbitrary messages, search for a specific one, or pick one at random.

This behavior often surprises developers coming from systems where messages or tasks can be introspected or filtered before processing. In this article, we’ll explore how to deal with this constraint and how to properly introspect a queue's content before republish part of it.

Two solutions to introspect RabbitMQ queues

There are two patterns to introspect and republish messages with RabbitMQ:

Screenshot of rabbitgui consume queue cta

RabbitGUI implements both solutions, each with its own advantages and disadvantages.

Peek and requeue

This approach allows you to peek at messages without permanently removing them from the queue. Messages are prefetched and stored in a local database, before being nacked and requeued back to RabbitMQ. The biggest downside of this solution is that it can only fetch the first 1000 messages from the front of the queue.

When messages are nacked and requeued, they are sent back to the front of the queue. Note that there is no guarantee that the order of messages is preserved, especially if there are multiple consumers consuming from the same queue. If your app does not need strict order preservation, this approach is perfectly fine.

It might also be worth noting that RabbitMQ might add headers to messages when they are nacked and requeued, such as x-death, x-delivery-count, or x-first-death-exchange, which you might want to avoid if your app or routing relies on it.

Consume and remove

This approach consumes messages from the queue and stores them in a local database. Messages are removed from the queue entirely, allowing you to consume the entire content of the queue without any limitations. The downside is that you have to re-publish messages back to RabbitMQ if you want to keep them.

This is the most robust solution. However, it requires you to re-publish messages back to RabbitMQ if you want to keep them, which can be a bit more work.

Reading random messages from a RabbitMQ queue

For both solutions, RabbitGUI stores messages in a local database on your machine, this lets you look at them, filter them, and eventually re-publish them where needed. To get started, open RabbitGUI and connect to your RabbitMQ server. Once connected, you can navigate to your queue and go to the "Consume" tab, choose the option you want to use, and hit "Extract messages".

Screenshot explorer rabbit mq dead letter queue messages

RabbitGUI saves whether each message was removed from the queue or requeued and lets you know by adding a "Local" badge to messages that only live in the local database and not in RabbitMQ anymore. You can mix both solutions at the same time.

You can filter any property of the message, such as the routing key, queue, or death count. This is useful if you want to find specific messages or if you just want to have statistics about the number of messages with each routing key for instance.

Rabbitmq filter messages

How to read messages headers in RabbitMQ?

Simply open the "Headers" tab of the message to list all of the message headers. RabbitGUI will display all the headers in a user-friendly way, allowing you to see the content of each header and its value.

As always with RabbitGUI, you can click on the name of a queue or exchange to navigate to it and see its details.

Rabbitmq message headers

How to re-publish messages from dead-letter queues?

RabbitGUI lets you re-publish all or only a subset of messages back to RabbitMQ. You can do this by selecting the messages you want to re-publish, going to "Actions", and selecting "Re-publish messages". You can also choose to re-publish all messages at once by clicking "Select all.

Screenshot republish messages from dead letter queue

You are presented with a modal where you can choose the destination queue and exchange. You can also choose to re-publish messages with a different routing key or a different exchange, which is useful if you want to re-route messages to a different queue.

To double-check what you are about to re-publish, RabbitGUI shows you a preview of the values it will use when you hit re-publish. This is a great way to ensure that you are not re-publishing messages that you don't want to.

Screenshot republish dead letter queue messages rabbit mq

How to throttle messages while re-publishing them with RabbitMQ

When re-publishing messages using RabbitGUI, you might want to avoid overwhelming your RabbitMQ server with too many messages at once. This is especially important if you are dealing with a large number of messages in your dead-letter queue. You can do this by enabling "Throttling" in the modal and choosing the desired rate.

Screenshot throtling messages rabbit mq

Conclusion

Even tho RabbitMQ does not allow you to peek into queues, you can still introspect dead-letter queues using RabbitGUI. It is a tool worth considering if you often deal with dead-letter queues and need to re-publish messages. If you still need to configure dead-letter routing on the broker, follow setting up dead-letter queues in RabbitMQ. For retry and backoff before messages land in the DLQ, see the RabbitMQ retry pattern.

More articles like that

How to spy on real-time queue traffic in RabbitMQ?ProductHow to spy on real-time queue traffic in RabbitMQ?Inspecting live messages flowing through a RabbitMQ queue is tricky because consuming is destructive. Learn how RabbitGUI creates a shadow queue to capture traffic without affecting your application.How to predict when a RabbitMQ queue will be empty?ProductHow to predict when a RabbitMQ queue will be empty?A step-by-step explanation of how to estimate backlog drain time for a RabbitMQ queue, from naive division to linear regression with adaptive windowing.Announcing RabbitGUI 1.1: Now on Windows and LinuxProductAnnouncing RabbitGUI 1.1: Now on Windows and LinuxRabbitGUI v1.1 brings native support for Windows, Linux, and Intel-based Macs, along with a built-in auto updater. Here's why this release matters.

RabbitGUI, the missing RabbitMQ IDE

Debug, monitor, and manage RabbitMQ with a modern developer interface.
Available on Windows, Mac, and Linux.

Try nowRabbitGUI screenshot

More articles about RabbitMQ

RabbitMQ Python Cheat-SheetCheat sheetRabbitMQ Python Cheat-SheetA comprehensive guide to using RabbitMQ with Python, including setup, producers, consumers, exchanges, and message handlingProperly setting up dead-letter queues in RabbitMQRabbitMQ tutorialProperly setting up dead-letter queues in RabbitMQLearn how to set up dead-letter queues in RabbitMQ, including creating a dead-letter exchange, binding it to a queue, and managing rejected messages via policiesRabbitMQ Golang Cheat-SheetCheat sheetRabbitMQ Golang Cheat-SheetEverything you need to know to get started with RabbitMQ in Go and Docker with code examples ready to go.