What Is New in RabbitMQ 3.13
RabbitMQ 3.13 introduces significant new capabilities, performance enhancements, and foundational changes that pave the way for future major releases. Here's a summary of the key updates.
| Category | Key Changes |
|---|---|
| New Features |
|
| Performance & Core |
|
| Operational & Tooling |
|
| Breaking Changes |
|
How does Khepri change RabbitMQ's cluster behavior?
Khepri is a new, experimental metadata store based on the Raft protocol, designed to eventually replace Mnesia. It's a major step towards predictable recovery from network partitions and node failures.
When enabled via rabbitmqctl enable_feature_flag khepri_db, RabbitMQ uses it for schema operations like declaring queues, exchanges, and bindings. The core difference is in consistency guarantees. With Mnesia, a schema change like creating a binding is confirmed only after all cluster nodes commit it. Khepri confirms the operation once a majority of nodes have accepted it.
In practice, this means applications using multiple connections to different nodes might see a brief period where a topology change isn't visible everywhere. If your application logic depends on immediate, cluster-wide visibility of such changes, you may need to introduce a short pause after declaring topology or ensure all components connect to the same node for coordination.
Key Implications:
- Predictable Recovery: Like quorum queues and streams, Khepri uses Raft, providing well-defined behavior during network splits.
- Majority Requirement: The cluster must keep a majority of nodes online for client operations to proceed.
- Future Default: This is a foundational change for RabbitMQ 4.x, where Khepri is planned to become the default.
This change is irreversible in 3.13, so test it thoroughly in non-production environments first.
What performance gains does Classic Queue v2 offer?
Classic Queue storage version 2 (CQv2) is now the recommended choice for all new deployments, offering substantial performance improvements over the older v1 implementation.
The most notable gains are for non-mirrored queues, especially when handling messages larger than the embedded threshold (default 4 KiB). CQv2's shared message store reduces memory footprint and improves throughput for these workloads. For mirrored queues, v2 also provides benefits, but note that mirroring itself is deprecated and slated for removal in RabbitMQ 4.0.
You should switch to CQv2 after upgrading all nodes in your cluster to 3.13. You can do this via a policy or a configuration setting. Using a policy is safer if you still have mirrored classic queues, as it avoids potential migration issues during a rolling upgrade.
# In rabbitmq.conf - for new clusters or after all nodes are on 3.13
classic_queue.default_version = 2
For existing queues, apply a policy that sets the x-queue-version argument to 2. The performance difference is often immediately noticeable in terms of lower memory use and higher message rates.
Why is the new internal message format important?
RabbitMQ 3.13 adopts a new, common internal message container heavily influenced by AMQP 1.0. This is a crucial architectural shift towards a protocol-agnostic core.
Previously, messages from different protocols (AMQP 0-9-1, MQTT, STOMP) were converted internally, which could lead to edge cases and data loss during cross-protocol routing. The new container encapsulates all data types and annotations needed by every supported protocol into a single, unified structure.
For you, this means more reliable and efficient multi-protocol support. Features like message routing between an MQTT publisher and an AMQP consumer, or dead-lettering across protocols, become more robust. It also simplifies future protocol additions and lays the groundwork for advanced cross-protocol features in RabbitMQ 4.x.
This change is mostly internal, but it's a significant enabler for the broker's future evolution.
What do I need to know about upgrading to 3.13?
Upgrading from 3.12.x to 3.13.0 is straightforward, but there are specific requirements and steps you must follow to ensure a smooth transition.
Erlang/OTP 26 is Mandatory: RabbitMQ 3.13 requires Erlang 26.x. Nodes will fail to start on older versions. Ensure your provisioning tools are updated.
Feature Flags: Unlike the 3.11 to 3.12 jump, you don't need to enable all feature flags before upgrading from 3.12. However, it's still a good practice to enable all non-experimental flags after a successful upgrade.
Mixed Version Clusters: You can run 3.13.0 nodes alongside 3.12.x nodes for a rolling upgrade. However, 3.13-specific features like stream filtering won't be available until all nodes are upgraded. Don't run mixed versions for extended periods.
Post-Upgrade Action: After the cluster is fully on 3.13, consider switching classic queues to CQv2 using a policy. Also, check for deprecated configuration like the old MQTT subscription_ttl setting and update it to max_session_expiry_interval_seconds.
How does stream filtering work and when should I use it?
Stream filtering allows consumers to subscribe to a subset of messages in a stream based on filter values, significantly reducing bandwidth usage between the broker and the application.
This is useful when you have a high-volume stream where different consumer applications are interested in different categories of data. Instead of every consumer receiving all messages and filtering locally, the broker performs the filter, sending only the relevant messages over the network.
You enable filtering during consumer creation by specifying filter values. The feature requires compatible client libraries. If you're using the RabbitMQ Stream Protocol, ensure your client is updated to a version that supports filtering.
Use this feature when you have a clear partitioning key in your message data (like a region or deviceType field) and consumers that only need specific slices of the stream. It optimizes network utilization and can reduce client-side processing overhead.
FAQ
Is Khepri ready for production use in 3.13?
No, Khepri is marked as experimental in RabbitMQ 3.13. The team encourages testing in development and staging environments to provide feedback, but it is not yet recommended for production workloads. Enabling the khepri_db feature flag is a one-way operation in this release.
I'm using mirrored classic queues. Should I switch them to CQv2?
Yes, CQv2 offers performance benefits for mirrored queues as well. However, you should use a policy to upgrade them, not the global classic_queue.default_version setting, to avoid issues during a rolling upgrade. Remember that classic queue mirroring is deprecated and will be removed in RabbitMQ 4.0.
My client uses MQTT. What do I need to change for 3.13?
First, ensure your client library supports MQTT 5.0 to take full advantage of the new protocol features. Second, update your broker configuration: the mqtt.subscription_ttl setting (in milliseconds) has been replaced by mqtt.max_session_expiry_interval_seconds (in seconds). A 3.13 node will fail to start with the old configuration key.
Why was rabbitmqctl node_health_check turned into a no-op?
This command had been deprecated for over three years. Its checks were simplistic and didn't reflect modern operational best practices. You should use more comprehensive health check endpoints provided by the management plugin or monitoring API instead.
What happens if I try to upgrade a node running Erlang 25?
The node will fail to start. RabbitMQ 3.13 has a hard dependency on Erlang/OTP 26.x. You must upgrade Erlang on all target machines before attempting to upgrade RabbitMQ.