RabbitMQ Quorum Queues

Quorum queues are the modern, recommended queue type for high-availability deployments in RabbitMQ. Introduced in version 3.8, they use the Raft consensus algorithm to replicate queue data across multiple cluster nodes. Quorum queues provide stronger consistency guarantees than classic mirrored queues and are the future of durable, fault-tolerant messaging in RabbitMQ.

The Voting Committee Analogy

A quorum queue makes decisions the same way a voting committee does. Before a message is confirmed as received, a majority (quorum) of nodes must agree that they have stored it. With 3 nodes, at least 2 must agree. With 5 nodes, at least 3 must agree. No single node can make unilateral decisions. Even if one node crashes, the majority still operates and the system continues without data loss.

How Raft Consensus Works (Simply)

Quorum queue "orders" on a 3-node cluster:

Producer publishes message:
  1. Leader node (Node1) receives the message
  2. Node1 replicates to Node2 and Node3
  3. When a majority (2 out of 3) confirm storage:
     Node1 + Node2 confirm  →  quorum achieved
  4. Leader sends ack to producer
  5. Message is now safely replicated

Node1 goes down:
  Remaining nodes (Node2, Node3) elect a new leader
  Queue continues operating - no data loss
  Two nodes still form a majority of 3-node cluster

Creating a Quorum Queue

Declare a quorum queue by setting the x-queue-type argument to quorum:

channel.queue_declare(
    queue='orders',
    durable=True,  # quorum queues are always durable
    arguments={
        'x-queue-type': 'quorum'
    }
)

In the Management UI: Go to Queues → Add a new queue → Set Type to "Quorum".

Quorum queues are always durable. You cannot create a non-durable quorum queue.

Quorum vs Classic Mirrored: Key Differences

Feature                Classic Mirrored       Quorum Queue
-----------------------------------------------------------
Consensus algorithm    Custom (eventual)      Raft (strong)
Message loss on crash  Possible               No (if quorum met)
Data guarantee         Best-effort sync       Confirmed before ack
Lazy mode support      Yes                    Not needed (built-in disk offload)
Priority queue         Supported              Not supported
Default queue type     Yes (old default)      No (set explicitly)
Recommended for new?   No                     Yes

Quorum Size

A quorum requires a majority of nodes to be available. Best practice is to run an odd number of nodes:

Cluster Size   Quorum   Can Tolerate
3 nodes        2 nodes  1 node failure
5 nodes        3 nodes  2 node failures
7 nodes        4 nodes  3 node failures

With 2 nodes, losing 1 node means losing the quorum — the queue becomes unavailable. Always deploy with at least 3 nodes for meaningful fault tolerance.

Replication Factor

By default, a quorum queue replicates to all nodes in the cluster. For large clusters, you can set a replication factor to limit how many nodes hold replicas:

rabbitmqctl set_policy QQ-Replication ".*" \
  '{"x-quorum-initial-group-size": 3}' \
  --apply-to quorum_queues

This limits each quorum queue to 3 replicas even in a 5-node cluster, reducing resource usage while maintaining fault tolerance.

Delivery Guarantees

Quorum queues guarantee that a message is stored on a majority of nodes before confirming receipt to the producer (when publisher confirms are enabled). This means:

  • No message is lost as long as a quorum of nodes remains available.
  • If the broker crashes after confirming a message, the message still exists on the surviving majority.

Consumer Behaviour with Quorum Queues

Consumers interact with quorum queues exactly as with classic queues. Use basic.consume, manual acknowledgements, and prefetch. Quorum queues support all standard consumer operations.

One difference: quorum queues track delivery counts. If a message is delivered and nacked (requeued) more than a configured number of times, it is considered a poison message and dead-lettered automatically:

channel.queue_declare(
    queue='orders',
    durable=True,
    arguments={
        'x-queue-type': 'quorum',
        'x-delivery-limit': 5  # dead-letter after 5 failed deliveries
    }
)

This built-in poison message detection is a major advantage over classic queues, where poison messages can cause infinite requeue loops.

Limitations of Quorum Queues

  • No support for message priority (x-max-priority)
  • No support for per-message TTL via expiration property (queue-level TTL via policy is supported)
  • No support for lazy mode (quorum queues manage memory and disk automatically)
  • Cannot convert an existing classic queue to quorum in place — you must create a new queue

Checking Quorum Queue Status

rabbitmqctl list_queues name type members leader online
name    type    members                              leader         online
orders  quorum  [rabbit@node1,rabbit@node2,rabbit@node3]  rabbit@node1   3

members shows all nodes with a replica. leader shows the current leader. online shows how many members are currently available.

Migrating from Classic to Quorum Queues

  1. Create the new quorum queue with the same name in a blue-green setup, or use a different name temporarily.
  2. Update producers to publish to the new queue.
  3. Drain the old classic queue (let consumers finish processing existing messages).
  4. Delete the old classic queue.
  5. Rename or reconfigure consumers to point to the quorum queue.

Summary

Quorum queues use the Raft consensus algorithm to ensure messages are safely stored on a majority of cluster nodes before confirming receipt. They eliminate message loss on node failure and provide automatic poison message detection via delivery limits. Always use an odd number of cluster nodes (3, 5, 7) for meaningful quorum. Quorum queues are the recommended queue type for all new high-availability deployments in RabbitMQ 3.8 and later, replacing classic mirrored queues.

Leave a Comment

Your email address will not be published. Required fields are marked *