Updated on 2023-05-06 GMT+08:00

Dead Lettering and TTL

Dead lettering and time to live (TTL) are two RabbitMQ features that must be used with caution because they may adversely affect system performance.

Dead Lettering

Dead lettering is a message mechanism in RabbitMQ. When a message is consumed, it becomes a dead letter message if any of the following happens:

  • requeue is set to false, and the consumer uses basic.reject or basic.nack to negatively acknowledge (NACK) the message.
  • The message has stayed in the queue for longer than the configured TTL.
  • The number of messages in the queue exceeds the maximum queue length.

Such a message will be stored in a dead letter queue, if any, for special treatment. If there is no dead letter queue, the message will be discarded.

For more information about dead lettering, see Dead Letter Exchanges.

Configuring dead letter exchanges and routing information using queue parameters

To configure a dead letter exchange for a queue, specify the x-dead-letter-exchange and x-dead-letter-routing-key parameters when declaring the queue. The queue sends the dead letter message to the dead letter exchange based on x-dead-letter-exchange and sets the dead letter routing key for the dead letter message based on x-dead-letter-routing-key.

The following example shows how to configure a dead letter exchange and routing information on a Java client.

channel.exchangeDeclare("some.exchange.name", "direct");

Map<String, Object> args = new HashMap<String, Object>();
args.put("x-dead-letter-exchange", "some.exchange.name");
args.put("x-dead-letter-routing-key", "some-routing-key");
channel.queueDeclare("myqueue", false, false, false, args);

TTL

TTL indicates the expiration time. You can configure TTL for messages and queues. Message TTL can be configured using the following methods:

  • Configure a TTL in queue properties: All messages in the queue have the same expiration time.
  • Configure a TTL for each message: Each message has a dedicated TTL.

If both methods are used, the smaller TTL value is used.

If a message that has stayed in a queue for longer than the TTL, the message will be discarded. If a dead letter exchange has been configured for the queue, the message will be sent to the dead letter exchange, and then routed to the dead letter queue.

For more information about TTL, see TTL.

Configuring queue TTL

The x-expires parameter in the channel.queueDeclare argument is used to control after how long of being unused a queue is automatically deleted. "Unused" indicates that there is no consumer in the queue, the queue is not re-declared, and the Basic.Get command is not invoked during this period. The value of x-expires must be a non-zero integer, in milliseconds.

The following example shows how to configure a queue TTL on a Java client.

Map<String, Object> args = new HashMap<String, Object>();
args.put("x-expires", 1800000);
channel.queueDeclare("myqueue", false, false, false, args);

Configuring message TTL

Configure a TTL in queue properties: Add the x-message-ttl parameter to the channel.queueDeclare argument. The value of this parameter must be a non-zero integer, in milliseconds.

The following example shows how to configure a message TTL by setting queue properties on a Java client.

Map<String,Object> arg = new HashMap<String, Object>();
arg.put("x-message-ttl",6000);
channel.queueDeclare("normalQueue",true,false,false,arg); 

Configure a TTL for each message: Add the expiration parameter to the channel.basicPublish argument. The value of this parameter must be a non-zero integer, in milliseconds.

The following example shows how to set a per-message TTL on a Java client.

byte[] messageBodyBytes = "Hello, world!".getBytes();
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                                   .expiration("60000")
                                   .build();
channel.basicPublish("my-exchange", "routing-key", properties, messageBodyBytes);