RabbitMQ Message TTL
TTL stands for Time-To-Live. In RabbitMQ, message TTL sets an expiry on messages — after a set amount of time, an unread message automatically expires. This prevents queues from filling up with stale messages that are no longer useful to consume.
The Newspaper Stand Analogy
A newspaper stand sells today's papers. If a copy is not sold by the end of the day, the stand owner throws it away — yesterday's news is not worth reading. Message TTL works the same way. If a message is not consumed within its expiry time, RabbitMQ discards it (or sends it to a dead letter queue).
Two Ways to Set TTL
1. Queue-Level TTL (applies to all messages in the queue)
Set the x-message-ttl argument when declaring a queue. Every message in that queue expires after the specified time in milliseconds, regardless of the individual message's own settings.
channel.queue_declare(
queue='short-lived-tasks',
durable=True,
arguments={
'x-message-ttl': 60000 # all messages expire after 60 seconds
}
)
2. Per-Message TTL (applies to one specific message)
Set the expiration property on a message when publishing. Only that specific message has the expiry, not the entire queue.
channel.basic_publish(
exchange='',
routing_key='my-queue',
body='This message expires soon',
properties=pika.BasicProperties(
expiration='30000' # expires after 30 seconds (as a string)
)
)
When Both TTL Values Are Set
If a queue has x-message-ttl set AND an individual message has its own expiration property, the message expires at whichever time comes first.
Queue TTL: 60,000 ms (60 seconds) Message TTL: 10,000 ms (10 seconds) --> Message expires after 10 seconds (the shorter time wins)
What Happens When a Message Expires
An expired message is either:
- Discarded silently — dropped from the queue and gone forever
- Dead-lettered — routed to a dead letter exchange (DLX) if the queue has
x-dead-letter-exchangeconfigured
Dead-lettering expired messages is the better production approach because it lets you audit, retry, or log the expired messages.
[Queue: "flash-sale-queue"]
x-message-ttl: 300000 (5 minutes)
x-dead-letter-exchange: "expired-dlx"
|
| message TTL runs out
v
[expired-dlx]
|
v
[expired-flash-sale-queue]
(for review or refund processing)
Queue Expiry vs Message Expiry
RabbitMQ also supports queue-level expiry via x-expires. This is different from message TTL. x-expires deletes the entire queue (including all its messages) if the queue has had no consumers for the specified time. It is useful for cleaning up abandoned temporary queues.
channel.queue_declare(
queue='temp-session-queue',
arguments={
'x-expires': 1800000 # delete the queue itself after 30 min of no consumers
}
)
Do not confuse x-message-ttl (expires individual messages) with x-expires (expires the whole queue).
TTL Precision
RabbitMQ checks for expired messages when they reach the head of the queue (the front, next in line for delivery). This means a message buried deep in a long queue may survive slightly longer than its TTL suggests — it is not evicted until it reaches the front. For queue-level TTL, expired messages are removed efficiently as soon as they are next to be delivered. Per-message TTL with varying expiration values can cause out-of-order expiry.
Real-World Use Cases for Message TTL
Session Tokens
A login service publishes a session token to a queue. The token is only valid for 15 minutes. Set x-message-ttl: 900000. If the consumer service is down for more than 15 minutes, expired tokens are automatically removed rather than processed by a consumer trying to validate a stale token.
Flash Sale Events
An e-commerce platform queues discount vouchers for a 1-hour flash sale. After the sale ends, any unread voucher messages expire automatically. Consumers never process vouchers from last week's sale.
Live Data Feeds
A stock price service publishes price updates every second. If a consumer is slow and falls behind, old price messages are useless. Set a short TTL (e.g., 5 seconds) so consumers always process fresh data rather than working through a backlog of stale prices.
OTP and Verification Codes
A two-factor authentication service queues OTP (One-Time Password) messages. OTPs expire after 5 minutes. Set expiration='300000' on each message. If the consumer has not processed the OTP in 5 minutes, it expires safely.
Checking TTL Configuration in the Management UI
Open the Queues tab and click on a queue. In the Features column, a queue with x-message-ttl shows the TTL value. You can also see TTL in the queue's arguments section at the bottom of the detail page.
TTL and Message Persistence
Setting a message as persistent (delivery_mode=2) does not override TTL. A persistent message still expires if its TTL runs out, even if it was saved to disk. Persistence protects against broker restart; TTL protects against message staleness. They are independent settings.
Summary
Message TTL in RabbitMQ controls how long an unread message can wait in a queue before expiring. Set queue-level TTL using x-message-ttl to apply a uniform expiry to all messages. Set per-message TTL using the expiration property for individual control. The shorter TTL always wins when both are set. Expired messages are either silently dropped or sent to a dead letter exchange. TTL is essential for keeping queues clean and ensuring consumers never process outdated data.
