RabbitMQ vs. Apache Kafka

ansd1 pts0 comments

RabbitMQ vs. Apache Kafka | RabbitMQ

Skip to main content

Version: 4.3On this page

Most existing comparisons of these two systems were written years ago by someone who sells one of them.<br>This one is written by the team that builds RabbitMQ, so bear that in mind — but we have tried hard to describe Kafka the<br>way its own documentation describes it, and we are explicit about the things Kafka does that<br>RabbitMQ does not. If anything here reads as unfair to you, we would genuinely like<br>to know — tell us.

The short version: the two systems started from opposite ends of the problem and have<br>been growing towards each other for years. RabbitMQ built its reputation as the<br>default choice for messaging and task queueing; Kafka built its reputation as the<br>default choice for event streaming. RabbitMQ then gained a durable, replicated log in<br>2021, and Kafka gained queue semantics in 2026. Their high-level capabilities now overlap<br>substantially.

If you are looking for a high-level summary and want to skip the technical details, you can jump directly to the use cases.

The line that used to divide them​

For a long time the advice was easy to give:

RabbitMQ for messaging and queueing, Kafka for streaming.

It was good advice. It is now out of date on both sides.

RabbitMQ has had a real log since 3.9 (2021). Streams are an<br>append-only, replicated, disk-based log with non-destructive reads, offset-based<br>positioning, retention policies and a dedicated protocol<br>built for throughput. RabbitMQ 3.11 (2022) added super streams<br>— partitioned streams — along with single active consumer, giving ordered,<br>partition-parallel consumption. Streams have been a mature, widely deployed feature for<br>several release series, not a recent bolt-on. This is not a queue wearing a log costume;<br>it is a log, designed as one, with the same mechanical sympathies that make Kafka fast.

Kafka has had queue semantics since 4.2 (2026).<br>KIP-932 "Queues for Kafka" introduced<br>share groups, production-ready as of Kafka 4.2. Share consumers acquire individual<br>messages under a time-limited lock, acknowledge them one at a time, and can outnumber<br>the partitions they read from. Kafka's own documentation is refreshingly direct about<br>why this was needed: "some traditional messaging workloads are not a good fit for<br>consumer groups."

The idea had been circulating for years. In April 2020 the RabbitMQ team sketched its own<br>design for competing readers over a stream —<br>strikingly close in shape to share groups in Kafka, four years before KIP-932 was filed. We claim no<br>influence; the log imposes similar constraints on everyone who builds this.

So the honest framing is not "log versus queue". It is: two mature systems, each of<br>which now does both things, each still carrying the assumptions of where it started.<br>Kafka's queue semantics are a consumption mode layered on a log. RabbitMQ's queue is a queue,<br>and RabbitMQ's log is a log.

Two models, side by side​

How RabbitMQ organises data​

RabbitMQ splits the problem in two. Publishers send to an exchange.<br>Bindings — rules attached to the exchange — decide which queues<br>or streams receive a copy.<br>Exchanges and bindings are just metadata living inside RabbitMQ that decide on the routing algorithm and therefore define the routing and messaging topology.

Behind the exchange you choose a queue type. Queue types are genuinely<br>different data structures storing your messages:

TypeStorageReadsBest atQuorum queueRaft-replicated log, fsynced before confirmDestructiveWork distribution where data safety and high availability mattersClassic queueLocal, per-message persistenceDestructiveTransient, high-churn, single-node queuesStreamReplicated append-only logNon-destructiveFan-out, replay, large backlogs, high throughputJMS queue (VMware Tanzu RabbitMQ)Raft-replicated log, fsynced before confirmDestructive or non-destructiveJMS applications needing selectors or queue browsersMQTT QoS 0 queueNoneDestructiveLow-latency fire-and-forget fanouts to MQTT QoS 0 subscribers<br>A single RabbitMQ cluster runs all of these at once.

How RabbitMQ streams organise data​

Streams deserve their own picture, because this is where the comparison with Kafka is<br>closest — and where readers coming from Kafka usually want a mapping.

A super stream is a logical stream partitioned into individual streams . Roughly:<br>a super stream corresponds to a Kafka topic, and a stream to one of its partitions.<br>The mapping is not exact, and the difference is worth understanding: a RabbitMQ stream<br>is a first-class, individually named object that exists on its own, whereas a Kafka<br>partition is a subordinate of a topic and has no independent identity. You can create,<br>bind, and consume a single RabbitMQ stream without any super stream in sight.

Two things in that diagram are worth calling out.

Stream protocol publishers write straight to the stream. A client using the<br>RabbitMQ Stream protocol discovers which node hosts the stream leader<br>and publishes to it directly, with no...

rabbitmq kafka stream queue streams high

Related Articles