Publisher Confirms are the mechanism RabbitMQ provides to ensure that a message sent by a producer has actually been received and processed by the broker.

Here’s a look at how it works in practice. Imagine a simple producer sending a message:

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.confirm_delivery() # Enable publisher confirms

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello, world!')

print(" [x] Sent 'Hello, world!'")

connection.close()

When channel.confirm_delivery() is called, RabbitMQ enters a special mode for that channel. Now, when basic_publish is called, the broker will not acknowledge the message as "sent" until it has been fully processed. This processing can mean several things: it’s been routed to at least one queue, or if the queue is configured as a quorum queue and the message needs to be replicated, it’s been replicated to a majority of nodes.

The broker signals this back to the producer on the same channel. A positive acknowledgement (ack) means the message was successfully handled. A negative acknowledgement (nack) means it wasn’t. The producer must listen for these acknowledgements.

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.confirm_delivery()

try:
    channel.basic_publish(exchange='',
                          routing_key='hello',
                          body='Hello, world!')
    print(" [x] Sent 'Hello, world!'")
    # This is the crucial part: waiting for the confirmation
    if channel.wait_for_confirms_or_ack():
        print("Message confirmed by broker")
    else:
        print("Message nacked by broker")
except pika.exceptions.AMQPError as e:
    print(f"Error during publish: {e}")
    # Handle connection errors or other AMQP issues

connection.close()

The wait_for_confirms_or_ack() method is synchronous. It blocks until an ack or nack is received. If you’re publishing many messages, this can be a bottleneck. For higher throughput, you’d use asynchronous confirms, typically with a callback function.

The system solves the problem of "fire and forget" messaging. Without confirms, a producer could send a message, the network could drop it, the broker could crash before receiving it, or the message could be rejected by the broker for some reason (e.g., queue full, policy violation). In all these scenarios, the producer would have no idea its message was lost. Publisher confirms provide that feedback loop.

Internally, when confirm_delivery() is enabled, RabbitMQ buffers outgoing messages from the producer on that channel. It doesn’t send them to the network immediately. Instead, it waits for internal processing to complete. Once the message is safely on disk (for durable messages) or replicated (for quorum queues) and routed, the broker sends an ack back to the producer. If anything goes wrong during this internal processing, a nack is sent.

The exact levers you control are primarily within the broker’s configuration and the producer’s code. On the producer side, you enable confirms and then must handle the ack/nack responses. On the broker side, the behavior of confirms is influenced by durability settings. A durable message written to a durable queue will only be confirmed after it’s been persisted to disk. If you’re using quorum queues, confirmation implies replication to a quorum. For classic mirrored queues, confirmation typically means the message has been accepted by the primary node.

What most people don’t realize is that wait_for_confirms_or_ack() can take a timeout. If the broker is slow to respond or unreachable, this call could hang indefinitely without a timeout. It’s good practice to set one, e.g., channel.wait_for_confirms_or_ack(timeout=5). A pika.exceptions.AMQPChannelError or pika.exceptions.AMQPConnectionError will be raised if the timeout occurs or if there’s a network issue preventing the ack.

The next logical step after ensuring your messages reach the broker is to guarantee they reach consumers, often through basic_ack on the consumer side.

Want structured learning?

Take the full Amqp course →