Adetayo Akinsanya unkletayo.dev

Distributed Message Queues: Log-Based (Kafka) vs AMQP Broker-Based (RabbitMQ)

Deconstructing message broker architectures, exchange routing, consumer offset polling, and message replay

Part 15 in Series — Catch up on the previous article: Event-Driven Systems: CQRS (Command Query Responsibility Segregation) & Event Sourcing (Part 14) before diving into this post.

Why You Need This in Real Life

An engineering team building a financial payment system needs an asynchronous messaging layer. A developer suggests using Apache Kafka because “it’s fast and handles millions of events.” Another developer insists on RabbitMQ because “it has smart routing exchanges.”

Three months after choosing Kafka, they hit a wall: they need complex message routing (e.g., routing an event to a specific queue based on header values region=us-east AND priority=high), and they need individual message-level acknowledgments and retries for dead-letter queues.

Kafka doesn’t support message-level routing exchanges or per-message queue deletions—it is an append-only distributed log.

Choosing between Log-Based Streaming (Kafka) and Smart Broker Queuing (RabbitMQ) is not about benchmark speed. It is a fundamental choice between two different architectural paradigms: Smart Broker / Dumb Consumer vs Dumb Broker / Smart Consumer.


Part 1: Architectural Paradigm Comparison

1. AMQP Smart Broker (RabbitMQ)
Producer ---> [ Exchange ] ---> (Routing Keys) ---> [ Queue 1 ] ---> Consumer A (Pushed Message)
                                               ---> [ Queue 2 ] ---> Consumer B (Deleted on Ack!)

2. Log-Based Event Stream (Kafka)
Producer ---> [ Distributed Partitioned Log ] ---> Consumer Group A (Offset 42 - Polls)
              [ M0 | M1 | M2 | M3 | M4 | M5 ] ---> Consumer Group B (Offset 10 - Replays!)
              (Immutable Log Retained on Disk)

1. Smart Broker / Dumb Consumer (RabbitMQ)

  • Broker State: The broker tracks message state (ACK, Unacked, Dead-Letter). Messages are deleted from the queue as soon as consumers acknowledge receipt.
  • Routing Engine: Flexible exchange types (Direct, Fanout, Topic, Headers) handle complex message routing rules.
  • Consumer Push Model: The broker pushes messages directly to active consumer worker threads over TCP sockets.

2. Dumb Broker / Smart Consumer (Kafka)

  • Broker State: The broker maintains an immutable, append-only log on disk. It does not track individual message consumption or delete messages upon receipt.
  • Offset Tracking: Consumers pull message batches at their own pace and track their reading position using integer offsets.
  • Message Replay: Because messages remain on disk until retention expiration (e.g., 7 days), consumers can rewind offsets to replay historic data.

Part 2: Feature & Capability Matrix

FeatureRabbitMQ (AMQP)Apache Kafka
Primary ParadigmMessage Queuing (Transient worker queues).Event Streaming (Persistent distributed log).
Data RetentionMessages deleted upon consumer ACK.Messages retained on disk for configured TTL or size limits.
Message ReplayImpossible (Data deleted upon consumption).Native capability (Rewind consumer offsets).
Message RoutingComplex routing (Exchanges, Topics, Headers).Simple key-based partition routing (MurmurHash2).
Ordering GuaranteesPer-queue ordering (Breaks under parallel consumers).Strict ordering per partition.
Consumption ModelPush-based (Broker pushes to consumer).Pull-based (Consumer polls broker batches).
Throughput Capacity20,000\sim 20,000 to 50,00050,000 msg/sec.1,000,000+1,000,000+ events/sec (Zero-Copy kernel transfer).

Part 3: Selecting the Right Engine for Your Architecture

Choose RabbitMQ When:

  1. You need complex routing rules (e.g., routing by priority, headers, or wildcards across multiple queues).
  2. You require granular per-message acknowledgment, dead-letter queues (DLQ), and selective retries.
  3. Your workload consists of discrete task commands (e.g., PDF generation, video encoding tasks) where messages are processed and immediately discarded.

Choose Apache Kafka When:

  1. You require high-throughput event streaming (100,000+100,000+ events/sec).
  2. You need to replay historical data (e.g., auditing, event sourcing, ML model re-training).
  3. You need strict event ordering per entity key across multiple scale-out consumers.
  4. You are building real-time stream processing pipelines (Kafka Streams, Flink).

Next Steps

Now that we understand message queues and event streams, we will enter Module 6 (Storage Systems & Global Scale Architectures): starting with LSM-Trees vs B+ Trees in Part 16.

References & Further Reading

  1. Sigelman, B. H., et al. (2010). Dapper, a Large-Scale Distributed Systems Tracing Infrastructure. Google Technical Report.
  2. W3C Recommendation. (2021). W3C Trace Context Specification (Traceparent & Tracestate). W3C Standard.
  3. Cloud Native Computing Foundation. OpenTelemetry Architecture & Signal Specifications. OpenTelemetry Docs.

Up Next in Series →

Part 16: Distributed Storage Engines: LSM-Trees (Cassandra/RocksDB) vs B+ Trees (Spanner/CockroachDB)

Continue to Part 16 →