3.0.0 #730
michaelklishin
started this conversation in
General
3.0.0
#730
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Changes between Bunny 2.24.0 and 3.0.0 (March 31, 2026)
Topology Recovery Improvements
Back in 2013-2014, RabbitMQ Java client's connection recovery was heavily
influenced by what was available in Bunny.
In 2025, Bunny starts adopting the features Java client has developed
over the years, starting with connection-level topology tracking.
Now all exchanges, queues, bindings recorded for topology recovery are stored
and maintained by
Bunny::Sessionand notBunny::Channel. This makesrecovery somewhat simpler and eliminates a class of problems where,
say, a queue was declared on one channel, deleted on another, and re-created
by Bunny's connection recovery contrary to the user's intent.
The only potentially breaking change here is: the client now intentionally skips
tracking queue and exchange declarations with
passive: true.GitHub issues: #704, #711
Reduced Connection Recovery Logging
On connections that have connection recovery enabled, certain I/O exceptions
are now logged at debug level to reduce log noise.
GitHub issue: #711
Topology Recovery Filters
Removed Versioned Delivery Tags
Versioned delivery tags introduced about as many problems as they have solved.
Originally introduced in 2013 shortly after automatic connection recovery,
they have been a polarizing feature for years.
3.0 is a good opportunity to remove them.
GitHub issue: #700.
Significant Publisher Performance Improvements
Publisher performance improvements (100K messages, with amq-protocol
2.4.0or later)with automatic publisher confirm tracking enabled (documented below):
wait_for_confirmsbasic_publish_batch(500)basic_publish_batch(1000)basic_publish_batch(2000)basic_publish_batch(3000)Bunny 3.0's confirm tracking is 3-4x faster than 2.x. Batch size of 1000
provides optimal throughput. Avoid batches over 3000 (they will perform worse due to
connection flow control on the RabbitMQ end).
To migrate from
2.x, simply replaceChannel#confirm_selectcalls withChannel#confirm_select(tracking: true).That's it.
In addition,
Bunny::Channel#basic_publish_batchbenefits further from the write hot path optimizationsthat do not benefit
Bunny::Channel#basic_publishmuch.Publisher Confirm Tracking
Bunny now supports publisher confirm
tracking, inspired by the .NET client 7.x
and Swift Bunny.
Use
basic_publish_batchfor optimal throughput (batch sizes of 500-3000 recommended):Single-message publishing is also supported but slower:
When
trackingis set totrue,outstanding_limitdefaults to 1000 (this is an optimal value according to the benchmarks, see below).This provides backpressure when too many messages are unconfirmed.
If the broker nacks a message, a
Bunny::MessageNackedexception is raised.Performance (100K messages, with amq-protocol
2.7.0):wait_for_confirmsbasic_publish_batch(500)basic_publish_batch(1000)basic_publish_batch(2000)basic_publish_batch(3000)Bunny 3.0's confirm tracking is 3-4x faster than 2.x. Batch size of 1000
provides optimal throughput. Avoid batches over 3000 (they will perform worse due to
connection flow control on the RabbitMQ end).
To migrate from
2.x, simply replaceChannel#confirm_selectcalls withChannel#confirm_select(tracking: true).With that single line you get automatic backpressure via publisher confirms and three times better throughput.
Important design note: unlike the .NET client 7.x and Swift Bunny, which both pause the caller per-message using the
async/awaitfeatures in those languages (this is very cheap: just suspends a task), Bunny in Ruby uses a watermark approach
with a shared condition variable. This avoids per-message mutex contention that has a dramatic negative performance effect.
Consumer Delivery Performance Optimizations
Several optimizations to reduce overhead in the consumer delivery hot path:
DeliveryInfo: hash representation is now lazily created only when accessed viato_hash,each, or[]; direct method access (e.g.,delivery_tag,routing_key)no longer allocates a hash, providing a roughly x2 speedup on microbenchmarks of very simplistic consumers
Consumer lookup caching: channels now cache the last consumer lookup, benefiting
the common single-consumer-per-channel pattern
Frame header buffer reuse: the transport layer now reuses a buffer when reading
frame headers, reducing per-frame allocations
Exchange Type Constants
Bunny::Exchangenow provides constants for all built-in and commonly usedexchange types:
TYPE_DIRECT,TYPE_FANOUT,TYPE_TOPIC,TYPE_HEADERS,TYPE_MODULUS_HASH,TYPE_LOCAL_RANDOM,TYPE_CONSISTENT_HASH,TYPE_RANDOM.Tanzu RabbitMQ Delayed Queue Support
Bunny::Queue::Types::DELAYEDandChannel#delayed_queuedeclare aTanzu RabbitMQ delayed queue with optional
:delayed_retry_type,:delayed_retry_min, and:delayed_retry_maxoptions.Tanzu RabbitMQ JMS Queue Support
Bunny::Queue::Types::JMSandChannel#jms_queuedeclare aTanzu RabbitMQ JMS queue with optional
:selector_fieldsand:selector_field_max_bytesoptions.Channel#reopenA new method that reopens a channel after a server-initiated closure
(e.g. due to a consumer delivery acknowledgement timeout or an unknown delivery tag).
The channel is reopened on the same connection, reusing its original channel id,
and its prefetch, confirm, and transactional settings are recovered.
Session#recover_channel_topologyRecovers topology (exchanges, queues, bindings, consumers) for a single channel.
Intended for use after
Channel#reopen.amq-protocolBumped to2.7.0(or Later)Bunny now requires
amq-protocol2.7.0or later for theChannel::Closepredicate methods (
#unknown_delivery_tag?,#delivery_ack_timeout?,#message_too_large?)that Bunny used to reinvent (with regular expression matches on
reply_text)Limit Hostname Resolution Time
Bunny now configures its TCP socket to limit the hostname resolution time,
assuming that the OS kernel supports the underlying socket option.
Breaking Changes
Except for the
VersionedDeliveryTagremoval, all breaking changes in this release are minor anddo not affect most codebases that use Bunny.
Bunny::Channel.newsignature has changed: the third positional argument is nowopts = {}(an option hash) instead of a consumer work pool.Use
Bunny::Session#create_channelor pass the work pool asopts[:work_pool]VersionedDeliveryTagremoved: delivery tags are now raw integersConsumer#recover_from_network_failurewas removed: topology recovery is now handled byBunny::SessionviaTopologyRegistryExchange#recover_from_network_failurewas removed: see aboveQueue#recover_from_network_failureandQueue#recover_bindingswere removed: see aboveThis discussion was created from the release 3.0.0.
Beta Was this translation helpful? Give feedback.
All reactions