Skip to content

Durability & Persistence

Everything so far assumed the broker keeps running. But brokers restart — deploys, crashes, kernel updates. The question that separates a toy setup from a production one is: when RabbitMQ restarts, what’s still there?

By default, disappointingly little. A queue and its messages live in memory, and a restart wipes them unless you asked for durability — and here’s the catch that trips up almost everyone: it takes two independent settings, and one without the other still loses your data.

Surviving a restart needs both of these to be true:

  1. The queue is durable. A durable queue’s definition is written to disk, so the queue still exists after a restart. Set durable: true when you declare it.
  2. The message is persistent. A persistent message’s body is written to disk. Set delivery_mode = 2 (persistent) when you publish it.

Miss either one and you lose data on restart:

flowchart TB
  a["durable queue +
persistent message"] -->|restart| a2["survives"]
  b["durable queue +
transient message"] -->|restart| b2["queue stays,
MESSAGES LOST"]
  c["non-durable queue +
persistent message"] -->|restart| c2["QUEUE GONE
(messages with it)"]
  d["non-durable +
transient"] -->|restart| d2["all lost"]
Only durable queue + persistent message survives a restart

The classic production incident: a team declares a durable queue, feels safe, and forgets to publish messages as persistent. The queue faithfully survives every restart — empty, because the messages inside it were transient. Durable queue, transient messages: the queue lives, the data dies.

// 1) durable queue — survives restart
await channel.assertQueue('orders', { durable: true });
// 2) persistent message — body written to disk
channel.sendToQueue('orders', Buffer.from(body), { persistent: true });

Writing to disk is slower than staying in memory, so persistence has a cost. But note an important subtlety: marking a message persistent does not guarantee it’s on disk the instant you publish — RabbitMQ may batch writes. To be certain a message is safely stored before you consider it sent, pair persistence with publisher confirms (previous lesson): the confirm arrives only after the message is safely persisted.

So the honest picture: durable queue + persistent message + publisher confirms is the fully-safe combination, and it trades some throughput and latency for not losing data across a restart. For high-volume, loss-tolerant streams (metrics, logs) you may deliberately skip persistence for speed — a legitimate choice, made consciously.

Classic durable queues survive a restart of one node — but a classic queue lives entirely on a single node, so if that node’s disk dies, the queue dies with it. Quorum queues raise the bar: they replicate the queue across several nodes using the Raft consensus algorithm, so the data survives the loss of a whole node, not just a restart. They’re the modern default for anything that must not be lost — and the Operations & Scaling module covers them in depth.

What two settings are BOTH required for a message to survive a broker restart?
You declare a durable queue but publish transient messages, then the broker restarts. What happens?
Why pair persistence with publisher confirms?
What do quorum queues add over a classic durable queue?