How to Set Up Rabbitmq with Dead Letter Exchanges and Message Ttl for Reliable Task Processing on Ubuntu Server
Learning how to set up RabbitMQ with dead letter exchanges and message TTL for reliable task processing on Ubuntu Server is one of the best ways to build a fault-tolerant messaging system. RabbitMQ is a powerful open-source message broker. It lets applications communicate asynchronously through queues. Without proper error handling, failed messages disappear silently. Dead letter exchanges (DLX) and message TTL solve this problem. They catch expired or rejected messages and route them to a dedicated queue for inspection or retry. In this tutorial, you’ll configure RabbitMQ on Ubuntu Server, create a dead letter exchange, set message TTL policies, and test the full flow. By the end, you’ll have a production-ready setup that handles task failures gracefully.
Prerequisites and Requirements for RabbitMQ Dead Letter Exchange Setup
Before you start, make sure you have the following in place.
System requirements:
- Ubuntu Server 20.04 or 22.04 (fresh install recommended)
- A non-root user with sudo privileges
- At least 1GB of RAM and 10GB of disk space
- A basic understanding of Linux terminal commands
Software you’ll need:
- RabbitMQ 3.10 or later
- Erlang (required by RabbitMQ)
- Python 3 with the
pikalibrary (for testing)
Assumed knowledge: You should be comfortable running commands in a terminal. You don’t need prior RabbitMQ experience. This guide explains each concept as you go.
Estimated time: 30–45 minutes from start to finish.
You can read the official RabbitMQ documentation for deeper background on exchanges and queues before proceeding.
How to Set Up RabbitMQ with Dead Letter Exchanges and Message TTL on Ubuntu
You might also find this useful: How to Configure Opnsense Firewall Rules for Network Segmentation
Follow these steps carefully. Each one builds on the last.
Step 1: Install Erlang and RabbitMQ
RabbitMQ depends on Erlang. Install both from the official RabbitMQ repository for the most stable versions.
sudo apt update && sudo apt upgrade -y
sudo apt install curl gnupg apt-transport-https -y
curl -1sLf 'https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/setup.deb.sh' | sudo bash
curl -1sLf 'https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/setup.deb.sh' | sudo bash
sudo apt update
sudo apt install erlang rabbitmq-server -y
Step 2: Start and enable RabbitMQ
Start the service and make it run automatically on reboot.
sudo systemctl start rabbitmq-server
sudo systemctl enable rabbitmq-server
sudo systemctl status rabbitmq-server
You should see active (running) in the output.
Step 3: Enable the RabbitMQ management plugin
The management plugin gives you a web dashboard. It makes debugging much easier.
sudo rabbitmq-plugins enable rabbitmq_management
sudo systemctl restart rabbitmq-server
Access the dashboard at http://your-server-ip:15672. The default credentials are guest / guest. These only work from localhost.
Step 4: Create an admin user
Create a new admin user for remote access. Replace adminuser and StrongPassword with your own values.
sudo rabbitmqctl add_user adminuser StrongPassword
sudo rabbitmqctl set_user_tags adminuser administrator
sudo rabbitmqctl set_permissions -p / adminuser "." "." "."
Now log in to the dashboard with your new credentials.
Step 5: Create the dead letter exchange and queues
You’ll define a dead letter exchange (DLX) and two queues. The main queue holds active tasks. The dead letter queue catches failed or expired messages.
sudo rabbitmqctl eval '
amqp_channel:call(
element(2, amqp_connection:start(#amqp_params_network{})),
#amqp_channel_open{}
).
'
It’s easier to do this with a Python script. Install the pika library first.
sudo apt install python3-pip -y
pip3 install pika
Create the setup script.
nano ~/setup_rabbitmq.py
Paste the following into the file.
import pika
credentials = pika.PlainCredentials('adminuser', 'StrongPassword')
connection = pika.BlockingConnection(
pika.ConnectionParameters('localhost', credentials=credentials)
)
channel = connection.channel()
# Declare the dead letter exchange
channel.exchange_declare(
exchange='dlx_exchange',
exchange_type='direct',
durable=True
)
# Declare the dead letter queue
channel.queue_declare(queue='dead_letter_queue', durable=True)
# Bind the dead letter queue to the DLX
channel.queue_bind(
queue='dead_letter_queue',
exchange='dlx_exchange',
routing_key='dead'
)
# Declare the main task queue with DLX and TTL settings
args = {
'x-dead-letter-exchange': 'dlx_exchange',
'x-dead-letter-routing-key': 'dead',
'x-message-ttl': 30000 # 30 seconds in milliseconds
}
channel.queue_declare(queue='task_queue', durable=True, arguments=args)
print("Setup complete.")
connection.close()
Save the file and run it.
python3 ~/setup_rabbitmq.py
This creates your main queue with a 30-second TTL. Any message that expires or gets rejected routes to dead_letter_queue automatically.
Step 6: Test the dead letter flow
Publish a test message and watch it expire into the dead letter queue.
nano ~/publish_test.py
import pika
credentials = pika.PlainCredentials('adminuser', 'StrongPassword')
connection = pika.BlockingConnection(
pika.ConnectionParameters('localhost', credentials=credentials)
)
channel = connection.channel()
channel.basic_publish(
exchange='',
routing_key='task_queue',
body='Test task message',
properties=pika.BasicProperties(delivery_mode=2)
)
print("Message published.")
connection.close()
python3 ~/publish_test.py
Wait 30 seconds. Then check the dead letter queue in the management dashboard. The message should appear there automatically.
Step 7: Apply a policy-based TTL (optional but recommended)
You can also set TTL using RabbitMQ policies. This avoids hardcoding values in your application code.
sudo rabbitmqctl set_policy TTL "task_queue"
'{"message-ttl": 60000}'
--apply-to queues
This sets a 60-second TTL on any queue matching the name task_queue. Policies override queue arguments for TTL, so use one approach consistently.
Troubleshooting Common RabbitMQ Dead Letter and TTL Problems
Problem: RabbitMQ won’t start
Check the logs for Erlang version mismatches.
sudo journalctl -u rabbitmq-server -n 50
Make sure your Erlang version matches the RabbitMQ compatibility chart on the official Erlang version compatibility page.
Problem: Messages don’t move to the dead letter queue
Check that you declared task_queue with the correct x-dead-letter-exchange argument. You can’t modify queue arguments after creation. Delete the queue and redeclare it.
sudo rabbitmqctl delete_queue task_queue
Then re-run your setup script.
Problem: TTL not working as expected
Remember that x-message-ttl is set in milliseconds. A value of 30000 equals 30 seconds. Double-check your value if messages expire too fast or too slow.
Problem: Can’t connect to the management dashboard remotely
The guest user only works from localhost. Make sure you created an admin user with full permissions in Step 4.
Warning: Don’t leave the default guest credentials active in production. Delete or restrict them.
sudo rabbitmqctl delete_user guest
Conclusion
You now know how to set up RabbitMQ with dead letter exchanges and message TTL for reliable task processing on Ubuntu Server.
