Skip to main content
Version: Next

AMQP 1.0

AMQP 1.0 is supported natively since RabbitMQ 4.0.

Version Negotiation

RabbitMQ natively supports both AMQP 1.0 and AMQP 0.9.1 out of the box, without requiring any additional plugins.

By default, RabbitMQ listens on port 5672, accepting connections for both AMQP 1.0 and AMQP 0.9.1.

After establishing a TCP or TLS connection and before sending any AMQP frames, the client sends a protocol header indicating whether it wants to use AMQP 1.0 or AMQP 0.9.1, as outlined in Section 2.2 Version Negotiation.

For AMQP 1.0 connections, RabbitMQ requires the use of Simple Authentication and Security Layer (SASL), as described in Section 5.3 SASL. If the client does not use SASL, RabbitMQ will reject the connection, as illustrated in Figure 2.13: Protocol ID Rejection Example.

Protocol Interoperability

RabbitMQ supports publishing and consuming messages across different protocols, which requires protocol conversions.

When a message is published using AMQP 1.0, all target queue types (classic queues, quorum queues, and streams) store the message in its original AMQP 1.0 format. If the message is later consumed using AMQP 1.0, no protocol conversion is necessary. Additionally, as mandated by the AMQP 1.0 specification, RabbitMQ ensures the immutability of the bare message. This allows clients to set message hashes, checksums, and digital signatures not only over the message body but also over the properties and application-properties sections.

Virtual Hosts

RabbitMQ supports logical multi-tenancy with virtual hosts.

If no virtual host was explicitly specified by the connecting application, the connection use the default_vhost configured in rabbitmq.conf:

default_vhost = /

AMQP 1.0 clients can connect to a different virtual host by prefixing the value of the hostname field in the open frame with vhost:.

For example, to connect to a virtual host called tenant-1, the client sets the hostname field to vhost:tenant-1.

Addresses

An AMQP 1.0 address determines where a message is sent to or consumed from. What internal object an AMQP address refers to and how an AMQP address is resolved is not defined by the AMQP 1.0 specification. Different AMQP 1.0 brokers can choose to interprete the provided address differently.

RabbitMQ implements the powerful and flexible AMQ 0.9.1 model comprising exchanges, queues, and bindings. Therefore, AMQP clients talking to RabbitMQ send messages to exchanges and consume messages from queues. Hence, the AMQP addresses that RabbitMQ understands and resolves contain exchange names, queue names, and routing keys.

RabbitMQ 4.0 introduces a new RabbitMQ specific AMQP address format, v2. The old RabbitMQ 3.x address format is referred to as v1.

important

AMQP clients should use address format v2.

Address format v1 is deprecated in RabbitMQ 4.0 and will be unsupported in a future RabbitMQ version. Whether format v1 is still supported is determined by the deprecated feature flag amqp_address_v1 whose deprecation phase is permitted_by_default in RabbitMQ 4.0.

Address v2

This section defines the new v2 address formats.

Target Address v2

The possible v2 target address formats are:

  1. /exchanges/:exchange/:routing-key
  2. /exchanges/:exchange
  3. /queues/:queue
  4. <null>

The first three formats are strings.

The 1st format /exchanges/:exchange/:routing-key causes all messages on the given link to be sent to exchange :exchange with routing key :routing-key.

The 2nd format /exchanges/:exchange causes all messages on the given link to be sent to exchange :exchange with the empty routing key "". This is useful for exchange types that ignore the routing key, such as the fanout exchange or the headers exchange.

Setting the default exchange "" in either of the first two formats is disallowed. Instead, use the 3rd format.

The 3rd format /queues/:queue causes all messages on the given link to be sent to queue :queue.
The queue must exist. Internally, this queue target still uses the default exchange. Hence, the user needs write permissions to exchange amq.default.

The first 3 formats require the target address to be the same for all messages on the given link. If different exchanges, routing keys, or queues need to be set for different messages on the same link, use the 4th format.

The 4th format is the AMQP null value. As explained in the AMQP extension Using the AMQP Anonymous Terminus for Message Routing, each message's to field of the properties section must be set. The allowed to address strings must have the same format, i.e. one of

  1. /exchanges/:exchange/:routing-key
  2. /exchanges/:exchange
  3. /queues/:queue

where the exchange must exist.

If a message cannot be routed, for example, because no queue is bound to the target exchange, RabbitMQ settles the message with the released outcome.

If a publishing application needs to publish (send) messages to

  • a single destination: prefer one of the first three string formats over the 4th (null) format as the first three formats provide slightly better performance
  • a small number of different destinations: prefer opening one link per destination with one of the first three formats
  • a large number of different destinations: prefer the 4th (null) format defining each destination in the to field

Source Address v2

The only valid v2 source address string format is

  1. /queues/:queue

where clients consume messages from queue :queue. The queue must exist.

Percent-encoding

Address format v2 requires exchange names, routing keys, and queue names to be percent-encoded according to RFC 3986.

For example, a client that wants to send to exchange amq.direct with routing key my-routing_key/123 must use target address /exchanges/amq.direct/my-routing_key%2F123.

Note that percent-encoding in address format v2 must be applied to all AMQP fields that require an address:

Address v1

warning

This section lists the deprecated v1 address string formats.

Target Address v1

  1. /exchange/:exchange/:routing-key
  2. /exchange/:exchange
  3. /topic/:routing-key
  4. /amq/queue/:queue
  5. /queue/:queue
  6. :queue
  7. /queue

The 1st format /exchange/:exchange/:routing-key causes all messages on the given link to be sent to exchange :exchange with routing key :routing-key. The equivalent v2 format is /exchanges/:exchange/:routing-key.

The 2nd format /exchange/:exchange causes all messages on the given link to be sent to exchange :exchange while the routing key can optionally be provided in the message subject field of the properties section. In v2, defining different routing keys per message requires setting the target address to the AMQP null value and the message to field to /exchanges/:exchange/:routing-key.

The 3rd format /topic/:routing-key causes all messages on the given link to be sent to RabbitMQ's default topic exchange called amq.topic with topic routing-key. In v2, use /exchanges/amq.topic/:routing-key.

The 4th format /amq/queue/:queue causes all messages on the given link to be sent to queue :queue (to be more precise, internally, to the default exchange with routing key :queue). Queue :queue must exist. In v2, use /queues/:queue.

The 5th format /queue/:queue has similar semantics to the 4th format. However, RabbitMQ will auto declare queue :queue, i.e. create such a queue if it doesn't exist. The queue is never auto deleted by RabbitMQ. In v2, use /queues/:queue. RabbitMQ 4.0 allows AMQP clients to create RabbitMQ topologies including queues with client defined queue types, properties, and arguments. Hence, there is no need for RabbitMQ itself to auto declare a specific queue for a given queue target address format.

The 6th format :queue is redundant to the 5th format.

The 7th format causes the message to be sent to the queue provided in the message subject field. In v2, to send messages to different queues, set the target address to the AMQP null value and the message to field to /queues/:queue.

Source Address v1

  1. /exchange/:exchange/:binding-key
  2. /topic/:binding-key
  3. /amq/queue/:queue
  4. /queue/:queue
  5. :queue

The 1st format /exchange/:exchange/:binding-key causes RabbitMQ to declare a queue and bind that queue to exchange :exchange with binding key :binding-key. Messages are then consumed from that queue.

The 2nd format /topic/:binding-key causes RabbitMQ to declare a queue and bind that queue to the default topic exchange amq.topic with topic filter :binding-key. Messages are then consumed from that queue.

The 3rd format /amq/queue/:queue causes RabbitMQ to consume from queue :queue. Queue :queue must exist.

The 4th format /queue/:queue causes RabbitMQ to declare a queue :queue and consume from that queue.

The 5th format :queue is redundant to the 4th format.

As explained previously, RabbitMQ 4.0 allows AMQP clients to create RabbitMQ topologies including queues with client defined queue types, properties, and arguments. Hence, there is no need for RabbitMQ itself to auto declare a specific queue for a given queue source address format. In v2, clients should first declare their own queues and bindings, and then attach with source address /queues/:queue which causes the client to consume from that queue.

Outcomes

An outcome indicates the result of delivery (message) processing at the receiver.

The following table describes the outcomes when the client is the sender/publisher/producer with RabbitMQ acting as the receiver:

AMQP 1.0 OutcomeEquivalent AMQP 0.9.1 FrameDescription
Acceptedbasic.ackAll queues the message was routed to have accepted the message. For example for quorum queues, this means a majority of quorum queue replicas have written the message to disk. The publisher can therefore forget/delete the message.
Rejectedbasic.nackAt least one queue the message was routed to rejected the message. This happens when the queue length is exceeded and the queue's overflow behaviour is set to reject-publish or when a target classic queue is unavailable.
RabbitMQ also rejects messages as specified in Using the AMQP Anonymous Terminus for Message Routing, for example if a message's to field of the properties section contains an invalid address or defines a non-existing exchange.
Releasedbasic.return (followed by basic.ack or basic.nack)RabbitMQ could not route the message to any queue. This indicates a topology misconfiguration, for example when no matching queue is bound to the target exchange.
ModifiedCurrently, RabbitMQ does not settle a message with the modified outcome.

The following table describes the outcomes when the client is the receiver/consumer with RabbitMQ acting as the sender:

AMQP 1.0 OutcomeEquivalent AMQP 0.9.1 FrameDescription
Acceptedbasic.ackThe consumer successfully processed the message. RabbitMQ can therefore delete the message.
Rejectedbasic.nack or basic.reject with requeue=falseThe consumer indicates that the message is invalid and unprocessable. RabbitMQ dead letters the message (or drops the message if dead lettering is not configured).
Releasedbasic.nack or basic.reject with requeue=trueThe consumer did not process the message. RabbitMQ requeues the message. The message will be delivered to the same or a different consumer.
ModifiedThe consumer did not process the message, but modified message annotations.
If undeliverable-here=true, RabbitMQ dead letters the message (or drops the message if dead lettering is not configured).
If undeliverable-here=false, RabbitMQ requeues the message.
See below for more information.

AMQP 1.0 vs. AMQP 0.9.1

As the name suggests, AMQP 1.0 is the more modern protocol. It is an ISO/IEC 19464 and OASIS standard, whereas AMQP 0.9.1 is not an official standard. For a more detailed comparison of the protocols, refer to our AMQP 1.0 blog posts.

Choosing the right protocol depends on several factors, including:

  • Feature Requirements: Whether you need specific features of AMQP 1.0 or AMQP 0.9.1.
  • Interoperability: If interoperability with other message brokers is important, note that more brokers support AMQP 1.0 than AMQP 0.9.1.
  • Client Library Availability: Whether supported client libraries are available for your programming language.

AMQP 1.0 Features

This section lists features that RabbitMQ supports exclusively in AMQP 1.0, which are not available in AMQP 0.9.1:

  • Fine Granular Flow Control as explained in the blog post Ten Benefits of AMQP 1.0 Flow Control:
    • A consuming client application can dynamically adjust and prioritize how many messages it wants to receive from specific source queues.
    • Safe and efficient use of a single AMQP connection for both publishing and consuming.
    • When one target queue is overloaded, publishers can continue sending at high speed to other target queues, and consumers can continue receiving at high speed from other source queues on the same AMQP connection.
    • Consumers can be stopped or paused and later resumed.
    • Graceful handoff from one single active consumer to the next, while maintaining message order.
    • The source queue can efficiently inform the consumer about an approximate number of available messages.
  • Queue Locality: RabbitMQ can provide up-to-date queue topology and leader information to clients.
    • For example, the RabbitMQ AMQP 1.0 Java client can leverage this information by trying to consume "locally" from a RabbitMQ node that hosts a queue replica and trying to publish "locally" to a node that hosts the queue leader.
    • This can result in lower intra-cluster traffic, reducing latency and increasing throughput.
  • Sender Settle Mode mixed: Allows a publisher to decide on a per-message basis whether to receive confirmations from the broker.
  • Modified Outcome: Allows a quorum queue consumer to add and modify message annotations when requeueing or dead lettering a message.
  • AMQP Filter Expressions: RabbitMQ implements properties and appliation-properties filters of AMQP Filter Expressions Version 1.0 Working Draft 09 when consuming from a stream via AMQP 1.0.
    • String prefix and suffix matching is also supported.
    • This feature allows multiple concurrent clients each consuming only a subset of messages while maintaining message order.
    • This feature reduces network traffic between RabbitMQ and clients by only dispatching those messages that the clients are actually interested in.
  • Well defined types
  • Better defined message headers
  • Enhanced Message Integrity: Clients can set message hashes, checksums, and digital signatures not only over the message body but also over the properties and application-properties sections, as the bare message is immutable.
  • Stream Message Fidelity: No loss of headers fidelity when storing or retrieving a message from a stream, since streams store messages in AMQP 1.0 encoded format.

AMQP 0.9.1 Features

This section lists features that RabbitMQ supports exclusively in AMQP 0.9.1, which are currently not available in AMQP 1.0:

Clients

Any AMQP 1.0 client should be able to communicate with RabbitMQ. The RabbitMQ team at Broadcom has developed two AMQP 1.0 client libraries specifically for RabbitMQ:

See the AMQP client libraries page for more information.

Currently, the AMQP 0.9.1 client ecosystem is more extensive, with a greater number of AMQP 0.9.1 client libraries supported by the RabbitMQ team at Broadcom.

Limitations

RabbitMQ does not support the following AMQP 1.0 features:

  • "Suspending" or "resuming" a link including
  • aborted field in transfer frame
  • dynamic field in source and target: clients can instead dynamically create server topologies (exchanges, queues, bindings) via HTTP over AMQP prior to attaching a link.
  • Transactions
  • Protocol Header for TLS Security Layer (Figure 5.1) including a protocol id of two. Instead, RabbitMQ runs a pure TLS server and therefore implements section 5.2.1.

Modified Outcome

Modifying message annotations with the modified outcome is supported in quorum queues, but not in classic queues. Modifying a message in a stream doesn't make sense given that a stream is an immutable log.

If field undeliverable-here is

  • true, classic queues and quorum queues will dead letter the message. If dead lettering is not configured, the message will be discarded.
  • false, classic queues and quorum queues will requeue the message.

The AMQP 1.0 Modified Outcome blog post describes use cases.

warning

The behaviour of undeliverable-here may change in a future RabbitMQ version.

For example, if undeliverable-here = true, instead of dead lettering the message, in the future, queues might requeue the message while ensuring that the message is not redelivered to the modifying link endpoint.