What Is New in RabbitMQ 3.10
RabbitMQ 3.10 focuses on improving core efficiency, adding new queue features, and enhancing operational tooling. The key updates are summarized below.
| Category | Key Changes |
|---|---|
| Core Server & Queues | Reduced memory footprint for quorum and classic queues. Quorum queues gain Message TTL, dead-lettering strategies, and safer requeue behavior. New classic queue backend (CQv2) available. |
| Performance & Efficiency | Lower per-queue garbage collection pressure, optimized inter-node message transfer, and faster definition import. |
| Operational & Management | Definition import can skip unchanged sources. Management plugin timestamps now use RFC 3339 format. Stricter validation for queue and consumer arguments. |
| Plugin Enhancements | MQTT plugin supports quorum queues for durable subscriptions. OAuth2 plugin adds scope alias mapping. Shovel and Consul plugins receive updates. |
| Bug Fixes & Compatibility | Includes fixes from 3.9.x, addresses regressions in large fanouts, stream delivery, and channel confirms. Requires Erlang 23.2+ (24.x recommended). |
How have quorum queues improved in 3.10?
Quorum queues see significant enhancements aimed at efficiency, new functionality, and operational safety.
Memory usage is now more predictable. Messages are moved to disk aggressively, ignoring the x-max-in-memory-length and x-max-in-memory-bytes policy settings. This reduces per-queue footprint and stabilizes latency.
New Features
- Message TTL: Quorum queues now support the per-message and per-queue Time-To-Live feature.
- Dead-Letter Strategies: You can choose between at-most-once (default, like 3.9) and at-least-once dead-lettering behavior.
- Safer Requeue: Negatively acknowledged messages are now placed at the back of the queue. This prevents a stuck consumer from bloating the Raft log. The old behavior (maintaining position) is preserved only if a redelivery limit is set.
These changes make quorum queues more versatile for stateful workloads where message expiry and guaranteed processing are important.
What is CQv2 for classic queues?
A new, optional backend for classic queues designed for lower and more consistent memory usage.
Dubbed CQv2, it comprises a new message store and queue index implementation. It aims to lower average memory consumption and improve consumer delivery efficiency, which can boost throughput when consumers keep pace with producers.
It's an opt-in feature. You enable it per-queue via policy or set it as the default in rabbitmq.conf. The original implementation (CQv1) remains the default for compatibility.
# Set via policy
rabbitmqctl set_policy cq_version "^cq\." '{"queue-version": 2}' --priority 1 --apply-to queues
# Or set as default in rabbitmq.conf
classic_queue.default_version = 2
In practice, this is a foundational change that reduces garbage collection pressure and sets the stage for future classic queue improvements.
What operational tools got better?
Several updates streamline day-to-day cluster management and configuration.
Definition Import: The boot-time import of definitions (queues, exchanges, etc.) is now smarter and much faster. If the source file hasn't changed, the import can be skipped entirely using definitions.skip_if_unchanged = true. The re-import process itself is over 100x faster in some cases.
Management API: Timestamps (like idle_since) now use the standard RFC 3339 format (e.g., 2022-03-22T11:39:37.908+01:00) instead of a custom UTC string. Clients must be able to parse this new format.
Monitoring: The Prometheus plugin had a bug fix for early startup exceptions, making metrics collection more reliable right after a node boots.
These improvements save time during restarts and make automation scripts more robust.
Which plugins have important updates?
The MQTT, OAuth 2, and Shovel plugins received notable feature additions and fixes.
MQTT Plugin
Durable MQTT subscriptions (QoS 1) can now be backed by quorum queues for better availability and recovery semantics. This is configured cluster-wide but only applies to new clusters or newly created subscriptions.
# In rabbitmq.conf
mqtt.durable_queue_type = quorum
Warning: Enabling this in an existing cluster with classic durable queues will prevent existing MQTT clients from re-subscribing until those old queues are manually deleted.
OAuth 2 Plugin
Added support for "scope aliases." This maps non-standard JWT claim values (like role names) to a set of RabbitMQ permissions, easing integration with identity providers that don't follow RabbitMQ's expected scope format.
Shovel Plugin
Dynamic Shovels can now be deleted or restarted from any node in the cluster, improving operational flexibility.
FAQ
Can I upgrade from 3.9.x to 3.10.0 directly?
Yes. RabbitMQ 3.10.0 nodes can run alongside 3.9.x nodes in a mixed cluster during a rolling upgrade. However, 3.10-specific features (like quorum queue TTL) are only available once all nodes are upgraded. Don't run mixed versions for extended periods.
Is the new classic queue backend (CQv2) stable?
It's a new implementation but is offered as an opt-in feature. The original CQv1 remains the default. For production use, test CQv2 with your workload and monitor memory and performance before rolling it out widely.
The requeue behavior for quorum queues changed. Will this break my application?
It might if your application logic depends on a requeued message keeping its original position in the queue. To retain the old behavior, you must set a redelivery limit (x-delivery-limit) on the queue. Otherwise, requeued messages go to the back.
Do I need to upgrade Erlang to use RabbitMQ 3.10?
RabbitMQ 3.10 requires Erlang 23.2 or later. Erlang 24.x is strongly recommended as it provides significant throughput improvements (20-50% for many workloads) and includes JIT support for ARM64.
How do I use quorum queues for MQTT durable subscriptions?
Set mqtt.durable_queue_type = quorum in your rabbitmq.conf before creating any durable subscriptions. This setting only affects newly created queues, so it's best applied to a new cluster. Existing classic queue subscriptions will not be converted.