Why is RabbitMQ not persisting messages on a durable queue?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
RabbitMQ is a widely used open-source message broker that supports complex routing scenarios and supports many messaging protocols. One of its core features includes message durability, which ensures that messages are not lost in the event of a broker restart or failure. However, users sometimes report that their messages aren't being persisted in queues declared as durable. Here, we explore why this occurs and how it can be addressed.
Understanding Message Durability
In RabbitMQ, durability of messages means that the messages will survive a broker restart. However, the durability of messages involves both the queue and the message itself. Here’s a look at each:
- Queue Durability: A durable queue will be recreated upon broker restart, preserving its configuration and properties.
- Message Durability: To ensure messages are not lost, they also need to be marked as durable. This ensures messages are written to disk rather than just held in memory.
Common Misunderstandings and Issues
1. Queue Only Durability Many users declare a queue as durable and assume this makes all messages durable. However, if the messages themselves are not marked as durable, they reside in memory only, and will be lost in a server restart or crash. This is the most common cause of missing messages in what's supposed to be a durable setup.
2. Confirming Message Delivery RabbitMQ provides acknowledgements to confirm message delivery. If a producer sends a message without confirming it has been queued, there's a risk of losing messages even before they reach the queue.
3. Publisher Confirms This is a feature where RabbitMQ confirms messages have been received and processed appropriately to the producer. Without this setup, even durable messages might not have been properly queued before a failure occurs.
Implementation Example
To ensure both the queue and messages are durable, consider the following code snippets:
RabbitMQ Misconfiguration
Misconfiguration can also lead to perceived losses where messages are ditched upon restart. Configuration parameters around memory and disk thresholds (e.g., vm_memory_high_watermark and disk_free_limit) can influence when RabbitMQ starts blocking new messages and when it writes messages to disk.
Performance Considerations
While making both messages and queues durable adds a level of safety against data loss, this can come with a performance cost due to disk I/O operations. It's crucial to strike a balance between durability needs and system performance, especially in high-throughput systems.
Summary Table
| Factor | Impact on Durability | Recommended Action |
| Queue Durability | High | Always declare queues as durable |
| Message Persistence | Critical | Set delivery_mode=2 in message properties |
| Publisher Confirms | Essential for reliability | Use confirmations in publisher code |
| System Configuration | Potential message loss | Ensure appropriate RabbitMQ configurations |
| Performance | Trade-off with durability | Optimize based on specific system needs |
Conclusion
Correctly implementing message and queue durability in RabbitMQ is essential for ensuring that no messages are lost during failures or restarts. This involves a combination of properly configuring the message broker, understanding the roles of message and queue durability, and carefully managing system resources. Through meticulous implementation and configuration, it's feasible to secure RabbitMQ setups against unexpected data losses.
Related reading
- Why is the kafka consumer consuming the same message hundreds of times?
- Why is the Kafka distributed connector dying when the node I created it on is killed?
- Why is the topics argument of KafkaUtils.createStream() a Map rather then array?
- Why Kafka consumer performance is slow?
- Why is Random Forest with a single tree much better than a Decision Tree classifier?
- Why is swap sometimes implemented by passing an array?
- Why is .Release.namespace rendered empty?
- Why is the accuracy for my Keras model always 0 when training?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.