πŸ›οΈ

Message Brokers Comparison: RabbitMQ vs Kafka vs ActiveMQ

System Architecture Intermediate 2 min read 300 words
Microservices

Message Brokers Comparison: RabbitMQ vs Kafka vs ActiveMQ

A comprehensive comparison of three popular message brokers for distributed systems.

Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Message Broker Landscape                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   RabbitMQ   β”‚      Kafka         β”‚          ActiveMQ              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Traditional  β”‚ Distributed        β”‚ JMS-compliant                  β”‚
β”‚ Message      β”‚ Streaming          β”‚ Enterprise                     β”‚
β”‚ Broker       β”‚ Platform           β”‚ Message Broker                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

RabbitMQ

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   RabbitMQ                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                  β”‚
β”‚  Producer ──▢ Exchange ──▢ Queue ──▢ Consumer   β”‚
β”‚                  β”‚                              β”‚
β”‚              Bindings                           β”‚
β”‚           (routing rules)                       β”‚
β”‚                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Features

  • AMQP Protocol: Standard messaging protocol
  • Exchange Types: Direct, Topic, Fanout, Headers
  • Message Acknowledgments: Reliable delivery
  • Flexible Routing: Complex routing patterns
  • Plugins: Extensive plugin ecosystem
  • Management UI: Built-in web interface

Exchange Types

Direct Exchange:
  Producer ──"order.created"──▢ Exchange ──▢ Queue (order.created)

Topic Exchange:
  Producer ──"order.*.created"──▢ Exchange ──▢ Queue (order.usa.created)
                                           ──▢ Queue (order.eu.created)

Fanout Exchange:
  Producer ──message──▢ Exchange ──▢ All bound queues

C# Example (using RabbitMQ.Client)

// Producer
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare("orders", ExchangeType.Topic, durable: true);
channel.QueueDeclare("order-processing", durable: true, exclusive: false);
channel.QueueBind("order-processing", "orders", "order.created");

var body = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(order));
channel.BasicPublish(
    exchange: "orders",
    routingKey: "order.created",
    body: body
);

// Consumer
channel.BasicConsume("order-processing", autoAck: false, consumer: new EventingBasicConsumer(channel)
{
    Received = (model, ea) =>
    {
        var body = ea.Body.ToArray();
        var message = Encoding.UTF8.GetString(body);
        ProcessOrder(message);
        channel.BasicAck(ea.DeliveryTag, multiple: false);
    }
});

Best For

  • Complex routing requirements
  • Request/Reply patterns
  • Traditional message queuing
  • RPC-style communication
  • Guaranteed delivery with acknowledgments

Apache Kafka

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Kafka Cluster                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚                    Topic: orders                     β”‚    β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€    β”‚
β”‚  β”‚Partition β”‚Partition β”‚Partition β”‚      ...         β”‚ β”‚    β”‚
β”‚  β”‚    0     β”‚    1     β”‚    2     β”‚                  β”‚ β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”˜    β”‚
β”‚                                                              β”‚
β”‚  Producers ────▢ Partitions ────▢ Consumer Groups            β”‚
β”‚                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Features

  • High Throughput: Millions of messages per second
  • Distributed Log: Append-only, immutable
  • Partitioning: Horizontal scalability
  • Replication: Fault tolerance
  • Consumer Groups: Parallel processing
  • Long Retention: Event sourcing capable
  • Stream Processing: Kafka Streams, ksqlDB

Partition Strategy

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                Partition Assignment                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                     β”‚
β”‚  Key-based: hash(order_id) % num_partitions        β”‚
β”‚                                                     β”‚
β”‚  Order 123 ──▢ Partition 0                         β”‚
β”‚  Order 456 ──▢ Partition 1                         β”‚
β”‚  Order 789 ──▢ Partition 2                         β”‚
β”‚                                                     β”‚
β”‚  Guarantees: Same key = Same partition = Ordering  β”‚
β”‚                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

C# Example (using Confluent.Kafka)

// Producer
var config = new ProducerConfig { BootstrapServers = "localhost:9092" };

using var producer = new ProducerBuilder<string, string>(config).Build();

await producer.ProduceAsync("orders", new Message<string, string>
{
    Key = order.Id,  // Ensures ordering per order
    Value = JsonSerializer.Serialize(order)
});

// Consumer
var consumerConfig = new ConsumerConfig
{
    BootstrapServers = "localhost:9092",
    GroupId = "order-processors",
    AutoOffsetReset = AutoOffsetReset.Earliest
};

using var consumer = new ConsumerBuilder<string, string>(consumerConfig).Build();
consumer.Subscribe("orders");

while (true)
{
    var message = consumer.Consume();
    ProcessOrder(message.Value);
    consumer.Commit(message);
}

Best For

  • High-throughput event streaming
  • Event sourcing architectures
  • Log aggregation
  • Real-time analytics
  • Replay of historical events
  • Microservices event bus

ActiveMQ

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   ActiveMQ                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                  β”‚
β”‚  JMS Producer ──▢ Destination ──▢ JMS Consumer  β”‚
β”‚                      β”‚                          β”‚
β”‚              Queue (P2P)                        β”‚
β”‚              Topic (Pub/Sub)                    β”‚
β”‚                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Features

  • JMS Compliance: Java enterprise standard
  • Multiple Protocols: AMQP, STOMP, OpenWire, MQTT
  • Persistence: KahaDB, JDBC
  • Clustering: Network of brokers
  • Virtual Destinations: Composite destinations
  • Message Groups: Related message processing

Destination Types

Queue (Point-to-Point):
  Producer ──▢ Queue ──▢ Single Consumer

Topic (Publish/Subscribe):
  Publisher ──▢ Topic ──▢ Subscriber 1
                      ──▢ Subscriber 2
                      ──▢ Subscriber N

Configuration Example

<!-- activemq.xml -->
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost">
    <destinationPolicy>
        <policyMap>
            <policyEntries>
                <policyEntry queue="orders.*" producerFlowControl="true"/>
            </policyEntries>
        </policyMap>
    </destinationPolicy>

    <persistenceAdapter>
        <kahaDB directory="${activemq.data}/kahadb"/>
    </persistenceAdapter>
</broker>

Best For

  • JMS-based enterprise applications
  • Legacy system integration
  • Multi-protocol support requirements
  • Traditional enterprise messaging

Comparison Matrix

Feature RabbitMQ Kafka ActiveMQ
Throughput Medium (~50k/s) Very High (~1M/s) Medium (~50k/s)
Latency Low (ms) Medium (ms) Low (ms)
Message Order Per queue Per partition Per queue
Delivery At-least-once, exactly-once At-least-once, exactly-once At-least-once
Retention Until consumed Time/size based Until consumed
Protocol AMQP Kafka Protocol JMS, AMQP, STOMP
Routing Rich (exchanges) Simple (topics) Moderate
Replay No Yes No
Clustering Built-in Native Network of brokers

Decision Guide

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  When to Use Which Broker?                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Need complex routing?          ──▢ RabbitMQ                   β”‚
β”‚  Need request/reply pattern?    ──▢ RabbitMQ                   β”‚
β”‚                                                                 β”‚
β”‚  Need high throughput?          ──▢ Kafka                      β”‚
β”‚  Need event replay?             ──▢ Kafka                      β”‚
β”‚  Need stream processing?        ──▢ Kafka                      β”‚
β”‚                                                                 β”‚
β”‚  Need JMS compliance?           ──▢ ActiveMQ                   β”‚
β”‚  Need multi-protocol?           ──▢ ActiveMQ                   β”‚
β”‚  Legacy Java integration?       ──▢ ActiveMQ                   β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Performance Characteristics

Throughput Comparison

Messages/second (approximate):

Kafka:     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 1,000,000+
RabbitMQ:  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 50,000
ActiveMQ:  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 50,000

Latency Comparison

Average latency:

RabbitMQ:  β–ˆβ–ˆ 1-2ms
ActiveMQ:  β–ˆβ–ˆβ–ˆ 2-3ms
Kafka:     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 5-10ms (but higher throughput)

Hybrid Architectures

Often, production systems use multiple brokers:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Hybrid Architecture                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  RabbitMQ ─────────▢ Request/Reply, Complex routing        β”‚
β”‚       β”‚                                                     β”‚
β”‚       β–Ό                                                     β”‚
β”‚    Kafka ──────────▢ Event streaming, Analytics            β”‚
β”‚       β”‚                                                     β”‚
β”‚       β–Ό                                                     β”‚
β”‚  ActiveMQ ─────────▢ Legacy JMS integration                β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Sources

  • Arhitectura/rabbitmq vs kafka vs activemq.gif

πŸ“š Related Articles