Bunny for Ruby: AMQP 0-9-1 messaging with RabbitMQ
Bunny is a popular, easy to use, mature Ruby client for RabbitMQ
At a glance
- What is it?
- Bunny is a Ruby client for RabbitMQ that supports modern CRuby releases and TruffleRuby without heavyweight dependencies. It fits Ruby services that need queues, exchanges, publisher confirms, manual acknowledgements, or RabbitMQ extension features, but it does not support JRuby or the RabbitMQ Stream protocol.
- Who is it for?
- Bunny is appropriate for Ruby and TruffleRuby services that use RabbitMQ through AMQP 0-9-1, especially when publisher confirms, manual acknowledgements, or RabbitMQ extensions matter. It is not suitable for JRuby or applications requiring the RabbitMQ Stream protocol.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 15 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 15, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Bunny's role in a Ruby-to-RabbitMQ service
Bunny solves the client-side problem of connecting Ruby applications to RabbitMQ. It speaks AMQP 0-9-1 and gives Ruby code an API for connections, channels, queues, consumers, exchanges, acknowledgements, and publisher confirms. The intended users are developers building services whose workflow crosses language or process boundaries. A Ruby web application can pass work to another service, while event collectors and analytics applications can receive messages from systems built with other technologies.
The useful distinction is between Bunny and RabbitMQ itself. RabbitMQ owns queues, routing, message delivery, persistence settings, and broker-side behavior. Bunny provides the Ruby-side interface to those services. It can participate in workflows ranging from a simple work queue to a multi-stage pipeline, but it does not replace the broker or turn an in-process Ruby queue into a distributed messaging system.
Bunny supports CRuby 3.2 through 4.0 and TruffleRuby. For TLS deployments, the README says the Ruby installation needs a recent enough OpenSSL version to include TLS 1.3 support. JRuby is outside the supported matrix. The README directs JRuby users to March Hare, which uses the RabbitMQ Java client and offers a similar API. That division matters because transport libraries are tied closely to their Ruby runtime rather than being interchangeable layers.
The project targets currently community-supported RabbitMQ release series. Its README also notes that AMQP 0-9-1 has evolved through extensions with few breaking changes, allowing Bunny operations to work across a wide range of RabbitMQ versions. That is a compatibility claim at the protocol and feature level, not a promise that every broker version has identical operational behavior. For example, the README specifically calls out the idempotency of `queue.delete` as a potentially breaking broker change.
Bunny connection, channel, queue, and delivery flow
The quick-start example exposes Bunny's central RabbitMQ object model. `Bunny.new` creates a client configuration object, `conn.start` opens the communication session, and `conn.create_channel` creates an AMQP channel. The application then declares a queue through `ch.queue("test1")`, subscribes a consumer to it, publishes a payload, acknowledges the received delivery, and closes the channel and connection.
The queue subscription uses `manual_ack: true`. This means the sample does not let RabbitMQ automatically remove the delivery after the callback returns. Instead, the callback receives delivery metadata and calls `ch.ack(delivery_info.delivery_tag)`. That explicit acknowledgement is significant for application design: callback execution and delivery completion are separate concerns, and the sample shows where the application decides that processing has succeeded.
Publishing uses `q.publish("Hello, everybody!")`. According to the example's comment, the message goes to the default exchange and is then routed to the queue. This is a small routing arrangement, not a general rule that publishing through a queue always behaves this way. RabbitMQ routing is more involved when applications declare exchanges and bindings, and the repository includes separate guides for exchanges, publishers, and bindings.
The example also calls `ch.confirm_select(tracking: true)` before publishing. Publisher confirms are therefore part of the demonstrated data-safety path. The README links this setting to RabbitMQ's publisher confirmation documentation, but it does not present the one-second `sleep` as confirmation of delivery. A real service still needs application-specific handling for confirmation failures, connection recovery, retries, and duplicate deliveries. The linked error-handling and durability guides are the relevant places to examine those concerns.
Bunny can perform basic operations on RabbitMQ Streams, according to the README, but it does not implement the RabbitMQ Stream protocol. A queue-oriented AMQP client should not be treated as interchangeable with a native stream consumer implementation.
Installing Bunny and publishing the first acknowledged message
For a Bundler-managed application, declare Bunny as a dependency. The README specifies version 3.0 or later for its example dependency declaration. Keep the constraint policy used by the application rather than treating this range as an automatic upgrade policy.
gem "bunny", ">= 3.0"For a direct RubyGems installation, the documented command is below. It installs the package into the current Ruby environment, so the correct executable or `sudo` policy depends on how that environment is managed.
gem install bunnyThe next example is a complete first use based on the README. It connects to RabbitMQ's default settings, enables tracked publisher confirms, declares `test1`, publishes one message, prints the consumed payload, acknowledges the delivery, and closes the client resources.
require "bunny"
conn = Bunny.new
conn.start
ch = conn.create_channel
ch.confirm_select(tracking: true)
q = ch.queue("test1")
q.subscribe(manual_ack: true) do |delivery_info, metadata, payload|
puts "This is the message: #{payload}"
ch.ack(delivery_info.delivery_tag)
end
q.publish("Hello, everybody!")
sleep 1
puts "Done"
ch.close
conn.closeWith a reachable RabbitMQ broker, the consumer should print `This is the message: Hello, everybody!`, followed by `Done`. The example's `sleep 1` only gives the consumer time to run. It does not configure RabbitMQ, establish a health policy, or replace an explicit result check. The repository also contains a `docker-compose.yml` for a development RabbitMQ and Toxiproxy environment, but the README does not provide a standalone `docker compose` tutorial, so this quick start is the clearer first path.
Bunny runtime constraints and failure boundaries
The largest explicit runtime limitation is JRuby support. Bunny says it no longer supports JRuby and recommends March Hare instead. An application that standardizes on JRuby must resolve the client choice before considering API compatibility or dependency changes. This is not a minor installation variant because March Hare is built on the RabbitMQ Java client rather than Bunny.
Bunny also has a clear protocol boundary. It implements RabbitMQ messaging through AMQP 0-9-1 and can perform basic operations on streams, but it does not implement the RabbitMQ Stream protocol. Teams choosing between queue-based messaging and stream consumption need to inspect their workload and required protocol rather than assuming that the Streams documentation link makes Bunny a native stream client.
The quick start does not configure authentication, TLS, virtual hosts, reconnection, timeouts, durable queues, dead-letter routing, or retry policy. Their absence does not mean Bunny cannot handle those concerns. The repository lists guides for connecting, TLS, error handling and recovery, durability, queues, consumers, exchanges, bindings, and extensions. It does mean the shortest example is not a complete production configuration.
Delivery handling also deserves scrutiny. Manual acknowledgement prevents RabbitMQ from treating the delivery as complete until `ch.ack` runs, while `confirm_select` addresses publisher confirmation. These controls solve different sides of the exchange. Neither should be read as a complete duplicate-processing strategy. The README points to RabbitMQ's data-safety and production checklist material, but it does not prescribe an application-wide retry or idempotency policy in the quick-start section.
Compatibility with an older or newer broker is also conditional. The protocol's history supports broad interoperability, yet RabbitMQ itself can change behavior across release series. The queue deletion idempotency note is an explicit example. Version verification belongs before migration, especially when automation depends on exact delete semantics.
Bunny maintenance, releases, and dependency cost
The repository is not archived, and its last push was on 2026-10-07. Recent releases include 3.4.0 on 2026-09-18, 3.3.0 on 2026-09-02, and 3.2.0 on 2026-08-27. These facts support recent project activity, but they do not remove the normal upgrade work associated with a Ruby library and a broker-facing protocol client.
The current documented runtime range is relatively narrow for CRuby, covering 3.2 through 4.0. Adopting Bunny can therefore constrain the supported Ruby versions an application chooses. Upgrading the Ruby runtime may require checking Bunny compatibility and the TLS requirements of the platform.
The repository also contains a gemspec, Gemfile, Rakefile, specs, examples, guides, and a custom licence file. GitHub classifies the licence as Other because it uses a custom licence. The actual obligations must be read from `LICENSE`; the repository summary does not establish whether redistribution, modification, notice retention, or other conditions apply. This review cannot give a legal conclusion, but an organization should not treat the licence as permissive by inference from the client being open source.
Upgrade cost also includes RabbitMQ behavior. Bunny targets community-supported RabbitMQ series, while topology declarations and feature expectations can connect application code to broker semantics. The separate guides for durability and RabbitMQ extensions make those dependencies visible. They should be reviewed when upgrading either side of the connection.
Bunny versus March Hare and native stream clients
March Hare is the documented alternative for JRuby. It offers a similar API but is built on the RabbitMQ Java client. That is the most relevant comparison because it addresses the same broad need, RabbitMQ access from a JVM-compatible Ruby runtime, while respecting Bunny's explicit JRuby boundary. The README does not claim that the two clients have identical internals, feature coverage, or operational behavior.
For CRuby and TruffleRuby users already using RabbitMQ's AMQP 0-9-1 model, choosing March Hare would move the project onto a Java-client-based design without solving a documented Bunny limitation. Bunny is the direct fit for those runtimes. Its documented feature set and lack of heavyweight dependencies are the relevant reasons to prefer it when RabbitMQ access is already required.
A native RabbitMQ stream client is a different category. Bunny's AMQP-oriented queues, exchanges, consumers, confirms, and acknowledgements fit workflows built around message routing and work distribution. The README explicitly says Bunny does not implement the RabbitMQ Stream protocol. If an application requires that protocol rather than basic stream operations over the supported client interfaces, an implementation of the stream protocol is the appropriate comparison point.
Editorial conclusion
Bunny is appropriate for Ruby and TruffleRuby services that use RabbitMQ through AMQP 0-9-1, especially when publisher confirms, manual acknowledgements, or RabbitMQ extensions matter. It is not suitable for JRuby or applications requiring the RabbitMQ Stream protocol. Before adoption, check the custom LICENSE file, confirm the broker and Ruby version in use, and review the relevant Bunny guides for connections, recovery, TLS, and durability.
Frequently asked questions
Which Ruby runtimes does Bunny support?
Modern Bunny versions support CRuby 3.2 through 4.0 and TruffleRuby. Bunny no longer supports JRuby.
How do I install Bunny with RubyGems or Bundler?
Use `gem install bunny` for a direct installation. In a Bundler-managed project, the README gives `gem "bunny", ">= 3.0"` as the dependency declaration.
Can Bunny use the RabbitMQ Stream protocol?
No. The README says Bunny can perform basic operations on RabbitMQ Streams but does not implement the RabbitMQ Stream protocol.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ruby-amqp-bunny)