Skip to content

Acknowledgements

Here’s the core question a queue must answer: if a consumer takes a message and then crashes before finishing, what happens to that work? Acknowledgements are the answer, and they’re the single most important reliability mechanism in RabbitMQ.

An acknowledgement (ack) is the consumer telling the broker: “I have fully processed this message — you can delete it now.” Until that ack arrives, RabbitMQ holds the message as unacknowledged and will redeliver it if the consumer’s channel dies.

There are two modes, and the difference is enormous:

  • Automatic ack (autoAck: true / auto_ack=True / autoAck: true): the message is considered delivered the instant it leaves the broker, before your code has touched it. Fast, but if your consumer crashes mid-processing, the message is gone — RabbitMQ already forgot it. This is at-most-once, and it silently loses work.
  • Manual ack: RabbitMQ delivers the message but keeps it as unacknowledged until you explicitly ack. If the channel closes without an ack, the message is redelivered to another consumer. This is at-least-once, and it’s what you want for any work that matters.

The rule: use manual ack for anything you can’t afford to lose.

With manual ack you have three responses:

  • ack — done, delete it.
  • nack (or reject) with requeue: true — I couldn’t process it; put it back for another attempt.
  • nack/reject with requeue: false — I couldn’t process it and retrying won’t help; drop it (or send it to a dead-letter exchange, if configured).

The redelivered flag on a delivery tells you “you’ve seen this one before” — a hint that a previous attempt failed, so you can treat it more carefully.

sequenceDiagram
  participant Q as Queue
  participant C as Consumer
  Q->>C: deliver (unacked)
  alt processed successfully
    C->>C: do the work
    C->>Q: ack
    Note over Q: message removed
  else consumer crashes
    C--xC: crash before ack
    Note over Q: no ack received
    Q->>C: redeliver (redelivered=true)
  end
Ack on success versus redelivery on crash
// noAck: false → manual acknowledgement
channel.consume('orders', async (msg) => {
if (!msg) return;
try {
await handle(msg.content);
channel.ack(msg); // done
} catch (err) {
channel.nack(msg, false, true); // requeue for another try
}
}, { noAck: false });
What is an acknowledgement in RabbitMQ?
Why is automatic ack risky for important work?
A consumer hits a transient error it wants to retry. What should it send?
What does the redelivered flag on a delivery indicate?