SkillByAIOpen interactive version →

Lesson 7 / 25

Acknowledgements

Use manual acknowledgements, nack and reject correctly.

A message is done only when acknowledged

When RabbitMQ delivers a message, it waits for the consumer to acknowledge it. With automatic acknowledgement (auto_ack=True), the broker considers the message delivered as soon as it is sent, so if the consumer crashes mid-processing, the message is lost. With manual acknowledgement, the consumer calls basic_ack after successfully processing; until then the message is unacked and, if the channel or connection closes, RabbitMQ requeues it for another consumer. To signal failure, call basic_nack (or basic_reject for a single message) with requeue=True to put it back, or requeue=False to discard it or, if configured, send it to a dead-letter exchange. Requeueing a message that always fails creates an infinite loop, so use requeue only for transient problems and dead-letter permanent failures. Acks must be sent on the same channel that received the delivery.

Delivered, unacked, acknowledged

A message stays unacked while being processed; ack removes it, nack requeues or dead-letters it.

Figure 3.1 — Ack, requeue or dead-letter after processing.

A consumer with manual acks

Ack on success, dead-letter permanent failures, requeue transient ones once.

def on_message(ch, method, props, body):
    try:
        process(json.loads(body))
        ch.basic_ack(delivery_tag=method.delivery_tag)
    except TransientError:
        # requeue once; if it was already redelivered, give up to the DLX
        ch.basic_nack(delivery_tag=method.delivery_tag, requeue=not method.redelivered)
    except Exception:
        ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)   # -> dead-letter exchange

channel.basic_qos(prefetch_count=20)
channel.basic_consume(queue="billing.orders", on_message_callback=on_message, auto_ack=False)
channel.start_consuming()

Forgotten acks cause memory growth

If a code path never acks or nacks, messages stay unacked until the consumer disconnects, and the queue looks stuck. Monitor the unacked count per queue and make sure every path ends in ack or nack.

Quick check: With automatic acknowledgement, what happens if a consumer crashes while processing a message?

  • The message is lost because it was considered delivered
  • The message is requeued automatically
  • The message goes to a dead-letter exchange
  • The broker restarts the consumer
Answer

The message is lost because it was considered delivered — Auto-ack treats delivery as completion, so a crash during processing loses the message.