MQTT Shared Subscriptions: Preserve Device-Level Ordering When Workers Scale
A shared subscription distributes matching publications among subscribing sessions; it does not promise that every message from one device stays with one worker or finishes in device order. If order matters, introduce an explicit per-device sequencing boundary before stateful effects occur. Increasing the worker count without that boundary can turn a valid input sequence into reordered application updates.
This guide uses the OASIS MQTT 5.0 Standard, 7 March 2019, section 4.8.2. The scope is one shared subscription with a known topic filter and a cooperating application worker pool. An original completion-order model was executed; no broker distribution algorithm, throughput or failover timing was measured.
Identify what the group actually shares
A shared filter has the form $share/group/filter. The complete shared-subscription identity includes both the group name and filter. Reusing a group name with different filters does not make those subscriptions one ordering domain.
For each publication, the server chooses one subscribing session for that shared subscription. The standard leaves the selection criteria to the implementation. Do not assume round-robin delivery, device-key hashing or sticky assignment unless the selected broker documents and qualifies that behavior.

Demonstrate the completion-order failure
Use a hypothetical device A with records one and two. Hold worker W1 while it processes record one, then let W2 finish record two. If workers update shared device state immediately on completion, the application’s visible sequence can become two then one even when the original producer emitted one then two.
The local model supplied completion arrivals A2, B1 and A1. A naive consumer exposed A’s order as two then one. A per-device gate held A2, committed B1 independently, then committed A1 and A2 when the missing predecessor arrived. This was a deterministic application-state model, not a claim about how a particular broker assigned those messages.
A low Receive Maximum on each worker does not solve this cross-worker problem. Each connection can obey its own protocol window while different workers finish related messages in different orders. Likewise, QoS describes a delivery exchange, not the completion order of arbitrary application work.
Choose the sequencing boundary
| Design | Where ordering is enforced | Required condition |
|---|---|---|
| Keyed serial dispatch | Before stateful processing | One active ordered owner per device key |
| Parallel preparation, ordered commit | Before visible effects | Preparation is safe without predecessor state |
| Broker-specific sticky distribution | Documented broker policy plus worker behavior | Exact failover/rebalance contract is qualified |
Keyed serial dispatch can use an ingress layer that routes each device to one bounded work lane. Parallel preparation can retain concurrency for independent decoding or validation, while a later gate applies results in sequence. It is not suitable if record two’s calculation already depends on the state produced by record one.
Do not perform an irreversible device action before the gate and call later database ordering a repair. The ordering requirement belongs at the effect that matters. If the product does not actually require strict order, document the commutative or latest-state rule instead of building a sequencer unnecessarily.
Define the per-device gate completely
- Identify the device stream and its generation, so sequence reuse after restart is not ambiguous.
- Load the expected next sequence from an agreed checkpoint or startup snapshot; do not assume every new consumer starts at one.
- Accept the expected record, commit its effect through the application contract, then advance the checkpoint.
- Hold later records in a bounded per-device gap buffer without applying their effects early.
- Handle already committed records through the approved duplicate/conflict policy.
- On a missing predecessor, stop, reconcile or reset that stream through a defined procedure instead of buffering forever.
Keep ownership migration explicit. When a device lane moves to another process, prevent two active owners from independently committing the same stream. The checkpoint and pending records need a handover rule appropriate to the storage system. MQTT shared-subscription membership alone does not implement that application ownership protocol.
Test the QoS-specific worker-loss boundaries
Section 4.8.2 permits a QoS 1 message whose selected worker loses its connection before acknowledgement to be sent to another group member. Test the case where the original worker applied an effect but its acknowledgement was lost; another delivery must not become an uncontrolled second effect.
The QoS 2 rule differs. Delivery already in progress must continue with the selected session when it reconnects; if that session terminates before reconnecting, the server must not send that application message to another shared subscriber. Therefore “use QoS 2” is not a universal worker-failover recipe.
A subscriber’s negative PUBACK or PUBREC also does not request another worker: the shared-subscription rule requires discarding that message rather than trying another subscriber. If the application needs retry elsewhere, design and verify that policy explicitly instead of assuming rejection means redistribution.
Establish startup state and acceptance evidence
Shared subscriptions do not send stored retained messages when a session first joins. Obtain any required device-state checkpoint through a separately defined bootstrap path before applying ordered updates. Do not infer a complete starting state from the first live message a new worker happens to receive.
Qualify with at least two workers and controlled delays. Capture application record identity, selected worker, receive time, preparation completion, commit sequence and acknowledgement. Add worker disconnect before and after local commit, session termination, membership changes and a deliberately missing predecessor.
Acceptance means each device’s required effects remain ordered across assignment and worker failure, while unrelated devices can still progress within their own bounds. Archive the broker policy, per-device ownership rule and gap-recovery tests. A balanced message count across workers is useful capacity evidence, but it is not evidence that device-level state transitions stayed correct.