Migrating to RabbitMQ Quorum Queues: Beyond Mirrored HA
RabbitMQ 4.0 removed classic mirrored queues. Quorum queues use Raft consensus for stronger durability, but require 3+ nodes, more disk I/O, and a migration strategy since in-place conversion isn't supported.
01 Sept 2026, 17:13 UTC

If you have been running RabbitMQ for a few years, you likely relied on classic mirrored queues for high availability. However, the era of mirroring is over. Classic mirrored queues suffered from complex edge cases during network partitions, potential data loss during synchronization, and unpredictable performance degradation when de-syncing nodes. With RabbitMQ 4.0, mirrored queues have been removed entirely. The industry standard now is the Quorum Queue.
The core takeaway is this: quorum queues are not just a replacement for mirrors; they are a fundamental architectural shift based on the Raft consensus algorithm. They offer significantly stronger durability and consistency, but they change how you must think about disk I/O and cluster topology.
The Raft Advantage: Consistency
Classic queues used a leader-follower model where replication was often asynchronous. If the leader crashed before a message reached the followers, that message vanished. Quorum queues use the Raft protocol to manage replication. In a quorum setup, a write is only acknowledged to the publisher once a majority of nodes (N/2+1) have persisted the message to their disk-based log.
This ensures that as long as a majority of your nodes are online, your data is safe and consistent. Because Raft is designed for consensus, you avoid the "split-brain" scenarios that frequently plagued mirrored queues during network partitions.
Practical Trade-offs and Constraints
Before migrating, you must understand that quorum queues are not a drop-in replacement for every workload. They are designed for durability over raw memory speed.
- Persistence Only: Quorum queues do not support transient messages. Every message is written to disk.
- Disk I/O Intensive: Because every message requires a replicated log write across multiple nodes, you will see higher disk I/O usage than with classic queues.
- Cluster Size: To achieve fault tolerance, you need a minimum of 3 nodes. A 2-node cluster cannot maintain a quorum if one node fails.
- Feature Limits: You cannot use per-message TTL (Time-To-Live) or per-message priority. These must be configured at the queue level.
Example: Declaring and Using a Quorum Queue
Since you cannot convert a classic queue to a quorum queue in-place, you must declare a new one and migrate your traffic. Here is how you declare a quorum queue using the rabbitmqadmin CLI and how to verify its status.
# Declare a quorum queue named 'orders_processed'
rabbitmqadmin declare queue name=orders_processed durable=true arguments='{"x-queue-type":"quorum"}'
To ensure your messages are actually reaching the quorum, your application must use Publisher Confirms. This ensures the client waits for the Raft leader to confirm the majority-write acknowledgment.
# Conceptual Python (pika) snippet for confirms
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.confirm_select() # Enable publisher confirms
try:
channel.basic_publish(exchange='', routing_key='orders_processed', body='order_data')
print("Message acknowledged by the quorum")
except pika.exceptions.AMQPMethodError:
print("Message was returned/failed to replicate")
Once the queue is running, you can verify the health of the Raft group using the following command:
# Check the status and leader location of all quorum queues rabbitmqctl list_quorum_queues name status leader replicas
The Migration Strategy
Since in-place conversion is unsupported, follow this pattern to migrate without downtime or data loss:
- Create the new quorum queue with the
x-queue-type: quorumargument. - Update Producers: Point your applications to the new queue name.
- Drain: Keep consumers running on the old classic queue until it is empty.
- Cleanup: Once the classic queue is zeroed out, delete it.
For high-volume cutovers, the Shovel plugin can move messages between queue types while producers are redirected, reducing the drain window.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.