Skip to main content
  1. AMQP 0-9-1: The Complete Protocol/

The AMQP 0-9-1 Architecture

The AMQP 0-9-1 Architecture #

AMQP 0-9-1 is a binary, bidirectional, message-passing protocol for communicating with a message broker. The specification defines not just a wire format, but a precise object model — exchanges, queues, bindings, consumers — and a behavioral contract for each object. Any two compliant implementations interoperate because the semantics are protocol-level, not implementation-level.

This is the foundational difference between AMQP and Kafka’s protocol. Kafka’s protocol is an implementation protocol: it exposes what Kafka’s internal architecture happens to look like (topics, partitions, offsets, consumer groups). AMQP is a design protocol: it specifies what a message broker should be, independent of any particular implementation.

The Broker Model #

An AMQP broker is a server that:

  1. Accepts connections from clients (producers and consumers).
  2. Receives messages from producers and routes them to queues via exchanges.
  3. Delivers messages from queues to consumers.
  4. Manages acknowledgments and redelivery.

The broker is a smart intermediary. In Kafka, a producer writes to a topic partition and a consumer reads from an offset — the broker stores and forwards but does not route. In AMQP, the broker actively routes: a producer publishes to an exchange with a routing key, and the broker decides which queues receive the message based on the binding table.

Kafka model:
  Producer → topic-partition (offset N) → Consumer reads from offset

AMQP model:
  Producer → exchange [routing-key] → [binding table] → queue(s) → Consumer

This routing flexibility is AMQP’s core value proposition. A single publish can fan out to multiple queues, be filtered to a specific subset of queues, or be discarded if no binding matches — all controlled by the exchange type and binding configuration, not by the producer.

Protocol Layering #

AMQP 0-9-1 runs over TCP. The layering is:

Application (producer/consumer logic)
    ↓
AMQP 0-9-1 protocol (frames, methods, content)
    ↓
TCP (reliable, ordered byte stream)
    ↓
Network

Within a single TCP connection, AMQP multiplexes using channels — independent logical sessions sharing the TCP socket. This is the key architectural primitive: one TCP connection, many parallel logical sessions.

The Entity Hierarchy #

AMQP 0-9-1 defines a strict hierarchy of entities:

Broker
└── Virtual Host (vhost)
    ├── Exchange
    │   └── Binding → Queue
    └── Queue
        └── Consumer

Virtual Host (vhost): an isolated namespace within the broker. Exchanges and queues in one vhost are completely invisible to another vhost. Connections attach to a specific vhost. A single RabbitMQ instance can host multiple independent messaging environments via vhosts.

Exchange: a routing agent. It receives messages published by producers and routes them to zero or more queues based on the exchange type and binding rules. Exchanges do not store messages.

Queue: a message store. Messages accumulate in a queue until a consumer retrieves them. Queues hold the actual messages; exchanges are stateless routing tables.

Binding: a rule that connects an exchange to a queue. A binding has a routing key (for direct and topic exchanges) or arguments (for headers exchanges). The binding table is the routing configuration: change bindings to change routing behavior without redeploying producers or consumers.

The Four Exchange Types #

The exchange type determines how the routing key in a published message is matched against the binding table:

Exchange typeRouting behavior
directRoute to queues bound with a routing key exactly matching the message’s routing key
fanoutRoute to all bound queues, ignoring the routing key
topicRoute to queues bound with a pattern that matches the message’s routing key (. delimiter, * one word, # zero or more words)
headersRoute based on message header values matching binding arguments, ignoring routing key

The exchange type is set at exchange declaration time and cannot be changed. The four types cover the routing needs of almost every messaging use case:

  • direct: point-to-point, work queues, event type routing
  • fanout: broadcast, notifications, cache invalidation
  • topic: multi-criteria routing, log levels + subsystems, event namespacing
  • headers: complex matching on structured metadata

The Default Exchange #

Every vhost has a default exchange: an unnamed direct exchange ("" or amq.default). Every queue is automatically bound to the default exchange with a routing key equal to the queue name. This means you can always publish directly to a named queue by publishing to the default exchange with the queue name as the routing key:

channel.basic_publish(
    exchange='',           # default exchange
    routing_key='my-queue',  # routes to queue named 'my-queue'
    body=b'hello'
)

The default exchange is how most introductory AMQP examples work — they are using the default exchange without naming it.

How AMQP Differs from Kafka Structurally #

Understanding AMQP requires letting go of the Kafka mental model. The differences are structural, not superficial:

DimensionAMQP 0-9-1Kafka
Storage unitQueue (FIFO, consumed and deleted)Partition (append-only log, retained by time/size)
Consumer modelPush (broker delivers to consumer)Pull (consumer polls for offsets)
Message fate after deliveryDeleted on acknowledgmentRetained regardless
RoutingExchange → binding → queue (broker-side)Producer chooses partition; consumer chooses offset
Consumer groupsCompeting consumers share a queueConsumer groups track independent offsets
ReplayNot supported (messages consumed once)Supported (seek to any offset)
Use caseTask distribution, RPC, event routingEvent streaming, audit log, replay

Neither model is superior — they solve different problems. AMQP is correct when messages are tasks (each must be processed exactly once by one worker), routing is dynamic (bindings change at runtime), or bidirectional RPC is needed. Kafka is correct when messages are events (retained, replayable), consumers are diverse (each tracks its own position), or ordering within a partition matters.

The Connection and Channel Model #

A client opens one connection (TCP session) to the broker. Within that connection, it opens one or more channels — lightweight virtual sessions multiplexed over the TCP connection. Each channel is independent: it has its own flow state, its own sequence of methods, its own consumer list.

TCP connection (one per client process)
├── Channel 1 (producer)
├── Channel 2 (consumer for queue A)
└── Channel 3 (consumer for queue B)

Why channels? TCP connection establishment is expensive (handshake, TLS negotiation, authentication). Channels amortize that cost: a client can maintain one TCP connection and use many logical sessions. The channel limit per connection is negotiated at connect time (typically 65535).

The general rule: one connection per process, one channel per thread. Sharing channels across threads is technically possible but requires explicit locking — AMQP method sequences on a channel must not be interleaved.

The AMQP Frame #

All communication over an AMQP connection is framed. A frame is the atomic unit of protocol exchange. Every method call, every message, every acknowledgment is expressed as one or more frames. The frame format is covered in Chapter 12; the key point here is that frames are the transport primitive — the way AMQP maps its object model onto the TCP byte stream.

The five frame types:

  • Method frame: carries a protocol method (declare exchange, publish, ack, etc.)
  • Content header frame: carries message metadata (properties, body size)
  • Content body frame: carries message payload (one or more, up to max-frame-size each)
  • Heartbeat frame: keepalive signal between client and broker
  • OOB (out-of-band) frame: rarely used, not covered here

Every message delivery is a sequence: method frame (basic.deliver) → content header frame → one or more content body frames. This framing enables the broker to stream large messages without buffering the entire body before forwarding.

Summary #

AMQP 0-9-1 defines a message broker as a routing intermediary between producers and consumers. Its entity model — exchanges route, queues store, bindings connect them, channels multiplex — is the vocabulary for every subsequent chapter. The four exchange types cover all standard routing topologies. The connection/channel architecture amortizes TCP costs. Everything else in the protocol — delivery semantics, acknowledgments, confirms, QoS — is built on top of this model.