Appearance
Replication
A spool is the storage unit that holds your queues: every queue lives in exactly one spool, and every account starts with one named default. Replication is what happens to a spool's data beyond one node.
Everything on this page is observable with an API key and curl, given two numbers set in the console when a spool is created. Both are immutable afterwards:
numReplicas– how many nodes hold the spool's data, primary included. The plan's replicas limit caps it – see limits.numSync– how many of the other copies must confirm a write before the response; at mostnumReplicas-1. The default spool takes the plan's replicas and the largestnumSyncthat keeps it writable with one node lost:numReplicas-2, so none on two replicas and one on three – see staying writable with a node lost.
What a response promises
Every write response – for example, a send's 201 or an ack's 204 – makes one promise: the primary wrote it to disk and synced, and numSync other copies confirmed it. The remaining copies catch up on their own; the response does not wait for them.
numReplicas | numSync | the write is on |
|---|---|---|
| 1 | 0 | one node |
| n | n-1 | every node holding the spool |
| n | 0 | the primary; the other copies follow, unconfirmed |
Losing a node
A spool is served by one node at a time, its primary. When that node is lost, requests answer 503 until the spool has a primary again; retry them.
- One copy. Nothing else holds the data. The spool waits for its node to return; losing that node's storage loses the spool's data.
- Synchronous copies. A copy's confirmation covers every write before it, so the copy furthest ahead holds every acknowledged write; it becomes the primary. No acknowledged write is lost.
- Asynchronous copies (
numSyncof 0). A copy becomes the primary with whatever it had received. Writes acknowledged after that point are lost. This is the price of not waiting.
A primary change never preserves in-flight leases: their messages are redelivered, and a settle presenting an old lease answers 410stale_token – see delivery.
Losing a copy
A write on a spool with numSync above zero does not return until that many copies confirmed it. While fewer are reachable, sends and settles wait; receives keep working – a lease is not durable state, as a primary change dropping every in-flight lease already shows. A client that gives up waiting must treat the write as unconfirmed: it may still take effect. The rule is the one for operation_unconfirmed – retry a send only on a queue with a dedup window, carrying the same key; see deduplication.
Staying writable with a node lost
A write waits for numSync of the other copies. With one of the spool's nodes lost – a copy, or a primary that a copy replaced – numReplicas-2 other copies remain to confirm. Writes keep returning while that is at least numSync, that is, while numReplicas >= numSync + 2.
numReplicas | numSync | with one node lost |
|---|---|---|
| 2 | 0 | writes return; the lost copy catches up when it is back |
| 2 | 1 | sends and settles wait: no other copy is left to confirm |
| 3 | 1 | writes return on the remaining copy's confirmation |
| 3 | 2 | sends and settles wait until two copies confirm again |
With every copy synchronous, each acknowledged write is on every node, and sends and settles stop for as long as any node is unreachable. A spool of three replicas with one synchronous keeps every acknowledged write through the loss of a node and keeps accepting writes through it. Two replicas cannot do both: with one synchronous they wait; with none they can lose acknowledged writes.
Choosing
numReplicasof 1 for development, tests, and data you can regenerate.numReplicasof at leastnumSync+2when sends and settles have to keep returning while a node is unreachable.- Every copy synchronous when a
201has to mean the write is on every node. Each write waits for the confirmations, and all writes wait while a node is unreachable; that is the cost. numSyncof 0 when the writes acknowledged in the moments before a node is lost are worth less than the wait. On two replicas the default spool chooses this: a primary change can lose the writes acknowledged since the other copy last caught up. SetnumSyncto 1 when that is unacceptable, and accept that sends and settles wait while the other copy is unreachable.
Copies add durability, not throughput: the primary serves every request.