How to Implement Delayed Message in RabbitMQ Easily
To implement delayed messages in
RabbitMQ, use the rabbitmq_delayed_message_exchange plugin which allows setting a delay per message via headers. Alternatively, use message TTL (time-to-live) with dead-letter exchanges to route messages after a delay.Syntax
RabbitMQ delayed messages can be implemented using the delayed message exchange plugin. You declare an exchange of type x-delayed-message and publish messages with a x-delay header specifying delay in milliseconds.
Alternatively, use TTL and dead-letter exchanges: set a message or queue TTL, and configure a dead-letter exchange to route expired messages to the target queue.
bash
rabbitmqadmin declare exchange name=delayed_exchange type=x-delayed-message arguments='{"x-delayed-type":"direct"}' rabbitmqadmin declare queue name=delayed_queue rabbitmqadmin declare binding source=delayed_exchange destination=delayed_queue routing_key=delayed_key # Publishing a message with delay header rabbitmqadmin publish exchange=delayed_exchange routing_key=delayed_key payload='Hello after delay' properties='{"headers":{"x-delay":5000}}'
Example
This example shows how to declare a delayed exchange and queue, then publish a message delayed by 5 seconds using the delayed message exchange plugin.
python
import pika # Connect to RabbitMQ connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # Declare delayed exchange args = {'x-delayed-type': 'direct'} channel.exchange_declare(exchange='delayed_exchange', exchange_type='x-delayed-message', arguments=args) # Declare queue and bind channel.queue_declare(queue='delayed_queue') channel.queue_bind(exchange='delayed_exchange', queue='delayed_queue', routing_key='delayed_key') # Publish message with 5000 ms delay headers = {'x-delay': 5000} properties = pika.BasicProperties(headers=headers) channel.basic_publish(exchange='delayed_exchange', routing_key='delayed_key', body='Hello after 5 seconds', properties=properties) print('Message published with delay') connection.close()
Output
Message published with delay
Common Pitfalls
- Not enabling the
rabbitmq_delayed_message_exchangeplugin before use. - Forgetting to set the
x-delayheader on the message. - Using TTL without configuring dead-letter exchanges, causing messages to be dropped instead of delayed.
- Confusing queue TTL and message TTL; message TTL allows per-message delay.
python
## Wrong: Publishing without x-delay header channel.basic_publish(exchange='delayed_exchange', routing_key='delayed_key', body='No delay') ## Right: Publishing with x-delay header headers = {'x-delay': 3000} properties = pika.BasicProperties(headers=headers) channel.basic_publish(exchange='delayed_exchange', routing_key='delayed_key', body='Delayed message', properties=properties)
Quick Reference
Delayed Message Exchange Plugin:
- Exchange type:
x-delayed-message - Message header:
x-delayin milliseconds - Requires enabling plugin:
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
TTL with Dead-Letter Exchange:
- Set
x-message-ttlon queue or message - Configure
x-dead-letter-exchangeto route expired messages - Used if plugin is not available
Key Takeaways
Enable the rabbitmq_delayed_message_exchange plugin to use delayed message exchanges.
Use the x-delay header to specify delay time in milliseconds per message.
Alternatively, use TTL and dead-letter exchanges for delayed message routing without plugins.
Always bind queues properly to the delayed exchange with correct routing keys.
Test delays carefully to avoid message loss or immediate delivery.