DevTools Hub

Search tools

Search for a developer tool

Kafka vs RabbitMQ

Part of the Distributed Systems Toolkit

The comparison usually gets framed as "which one is faster" or "which one scales better," as if Kafka and RabbitMQ were two competing implementations of the same thing. They aren't. They're built on opposite architectural premises — one keeps the broker smart and the consumer simple, the other keeps the broker simple and pushes intelligence to the consumer — and that single design split, not raw throughput, is what actually decides which one fits a given job. Message Queues Explained covers the shared vocabulary (delivery guarantees, queue vs topic, visibility timeout) this post builds directly on top of.

Smart broker, dumb consumer — or the reverse

RabbitMQ is a smart broker. It tracks, per message, whether a consumer has acknowledged it; it applies routing logic (which queue a message even goes to) as the message arrives; and once a message is acked, the broker deletes it — there's nothing left to look at afterward. The consumer's job is comparatively simple: receive, do the work, ack.

Kafka inverts this. The broker is close to a dumb, append-only log — it doesn't track per-message delivery state at all, and it doesn't delete a message on consumption. A message sits in its partition for as long as the topic's retention policy allows, whether or not anyone has read it yet. The intelligence — which messages this specific consumer has already processed — lives entirely in the consumer, as an offset it tracks and commits back to Kafka. Ask Kafka "has this message been consumed?" and the honest answer is that the broker doesn't know or care; only a specific consumer group's committed offset means anything.

Producer
publish
Exchange
topic exchange, key: orders.*
route by key
Queue
order-1order-2
order-1 deleted from the broker once acked
deliver
Consumer

RabbitMQ: the broker owns routing and per-message ack state. Once order-1 is acked, it's gone — there's nothing to replay.

Producer
publish, hashed by key
Partition 0
retained per policy
m0m3
Partition 1
retained per policy
m1m4
Partition 2
retained per policy
m2m5
1 partition : 1 consumer / group
Consumer 1
reads partition 0, offset 2
Consumer 2
reads partition 1, offset 2
Consumer 3
reads partition 2, offset 2

Kafka: messages stay put regardless of consumption; each consumer tracks its own offset. A second, independent consumer group would read the same partitions from the start, untouched by the first group's progress.

What that split actually causes

RabbitMQKafka
Consumer modelBroker pushes (prefetch/QoS controls flow)Consumer pulls (poll loop)
Replay a past messageNot possible once acked — it's deletedTrivial — reset the consumer group's offset
Ordering scopePer queue (single consumer preserves it)Per partition
Native message TTL / priorityYes, first-class queue/message argumentsNo — not a broker concept
Native dead-letter queueYes — a queue argument (DLX)No core concept — Kafka Connect has one for connectors specifically, not the core producer/consumer API
Native RPC (request/reply)Yes — reply-to + correlation ID, both core AMQP fieldsNo — has to be built on top
Coordination serviceNone requiredNone, as of KRaft mode (production-ready since 3.3, 2022) — earlier versions required ZooKeeper

Throughput: not really the deciding factor

Kafka is built for sustained, very high throughput — partitioned, sequential disk writes, and batched network transfer are the whole design. RabbitMQ's overhead is the direct cost of what it's doing per message that Kafka isn't: evaluating routing logic and tracking individual delivery state. That difference is real, but it rarely ends up being the actual constraint — most systems don't run either broker anywhere close to its throughput ceiling. The architectural question (do you need replay, complex routing, RPC, or per-message priority) almost always matters more in practice than which one wins a raw messages-per-second benchmark.

When each one actually wins

  • Reach for RabbitMQ when the job is a task queue: work items that get processed once and are done, complex routing between services, per-message priority or delay, or RPC-style request/reply where a service asks another service a question and waits for a specific answer.
  • Reach for Kafka when the job is an event stream: something happened, and multiple independent consumers — today and ones that don't exist yet — need to read that history, potentially from the beginning. Event sourcing, change-data-capture pipelines, log aggregation, and analytics all depend specifically on replay, which RabbitMQ's delete-on-ack model structurally can't give you.

They aren't mutually exclusive in one system — a common real pattern is Kafka as the durable event backbone multiple services read from independently, with RabbitMQ handling task distribution and RPC inside a specific service that needs that pattern. Picking one to standardize on everywhere trades away exactly the strength the other one has.

Try it yourself

Throughput Calculator applies directly to sizing either one — model whether N parallel consumers (Kafka: bounded by partition count; RabbitMQ: bounded by however many you run against one queue) can actually keep up with a given arrival rate and per-message processing latency.

FAQ

Is Kafka just a faster, more modern RabbitMQ?

No — "faster" isn't the axis they differ on. Kafka trades away RabbitMQ's per-message broker intelligence (routing, ack tracking, priority, TTL, RPC) specifically to get durable replay and very high sustained throughput. A system that needs what RabbitMQ does natively doesn't get it back by switching to Kafka and building it manually — it has to be built from scratch on top of a broker that was never designed to provide it.

Can RabbitMQ do what Kafka does?

Not the core replay capability — once a message is acked, RabbitMQ has deleted it, and there's nothing left to replay from. Quorum queues and streams (a newer RabbitMQ 3.9+ feature explicitly modeled on Kafka's log) narrow this gap for specific use cases, but the default RabbitMQ queue is fundamentally a delete-on-ack structure, not a retained log.

Do I need ZooKeeper to run Kafka?

Not anymore — KRaft mode, which replaces ZooKeeper with a built-in Raft-based metadata quorum, has been production-ready since Kafka 3.3 (2022). Older deployments and documentation predating that will still assume a separate ZooKeeper cluster, which is worth checking for before assuming a given setup guide is current.

Related tools