0
0
RabbitmqHow-ToBeginner · 4 min read

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_exchange plugin before use.
  • Forgetting to set the x-delay header 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-delay in milliseconds
  • Requires enabling plugin: rabbitmq-plugins enable rabbitmq_delayed_message_exchange

TTL with Dead-Letter Exchange:

  • Set x-message-ttl on queue or message
  • Configure x-dead-letter-exchange to 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.