flowchart TD
A["A message to send"] --> B{"Is losing it acceptable?"}
B -->|Yes| Q0["QoS 0: at most once"]
B -->|No| C{"Are duplicates acceptable?"}
C -->|Yes| Q1["QoS 1: at least once"]
C -->|No| Q2["QoS 2: exactly once"]
7 MQTT QoS Levels
7.1 Start With The Consequence Of Losing One Message
QoS is not a badge for the whole system; it is a decision for each message family. A replaceable temperature sample can disappear with little harm, a door-open alert should arrive at least once, and a narrow audit command may need duplicate control. Begin with the consequence of loss or duplication, then choose the smallest MQTT QoS that matches it.
7.2 QoS Is a Message-Family Decision
MQTT Quality of Service controls how hard the protocol tries to deliver a message between a client and the broker. It is not a single setting for an entire device. A useful IoT design chooses QoS per message family: frequent telemetry, important events, commands, retained state, and workflow acknowledgements may all need different handling.
The tradeoff is reliability evidence versus overhead. Higher QoS adds acknowledgement state and retry behavior. That can be exactly what an alarm or command needs, but it is often wasteful for replaceable sensor readings where the next value arrives soon.
Broker Bex
“A message with no subscriber is a tree falling in an empty forest — design the topic before the payload.”
In this chapter, Bex prices each guarantee on the board: what the acknowledgement costs, and who is still subscribed when the retry finally lands.
Start the decision with consequence, not protocol vocabulary. If a dropped value is replaced by the next sample and the dashboard can show freshness, QoS 0 keeps radios quiet and broker state small. If a door-open event or threshold crossing must reach a workflow but can be deduplicated with an event id, QoS 1 is usually the practical middle. If a duplicate protocol delivery would be harmful, first redesign the message as a desired-state command; only then consider QoS 2 for a narrow family with a clear audit need.
If you only need the intuition, this layer is enough: use QoS 0 for replaceable telemetry, QoS 1 for important events that can tolerate duplicates, and QoS 2 only when duplicate protocol delivery would be unsafe and cannot be handled by idempotent design.
Write that decision into topic documentation. For example, site/+/temperature can state "QoS 0, max staleness 30 seconds", while site/+/alarm/open can state "QoS 1, event id required". The label keeps firmware, broker policy, and dashboard expectations aligned.
The Three Contracts
QoS 0: At Most Once
The message is sent without a protocol acknowledgement. This fits high-rate, replaceable telemetry where occasional loss is acceptable.
QoS 1: At Least Once
The sender keeps state until an acknowledgement arrives. Delivery is retried, so the receiver must tolerate possible duplicates.
QoS 2: Exactly Once
The sender and receiver use a multi-step handshake to avoid protocol-level duplicates. Use it sparingly because it adds state and round trips.
Bex’s Topic Board
- Topic: the promise lives in topic documentation —
site/+/alarm/opendeclares “QoS 1, event id required.” - QoS: each step up buys acknowledgement state and retries; the QoS 2 handshake adds round trips.
- Subscriber: an at-least-once receiver meets the same event twice — deduplication is its job, not the broker’s.
Beginner Examples
- A temperature reading published every few seconds is usually QoS 0: the next reading replaces a lost one.
- A door-open event is often QoS 1: the event matters, and duplicate handling can be done with event IDs or idempotent processing.
- A non-idempotent command should first be redesigned as a safe state-setting command. If duplicate execution is still unsafe, QoS 2 may be justified.
Overview Knowledge Check
If this is enough, stop with the message-family rule. Continue to Practitioner when you need to document a selection record for a real fleet.
7.3 Write the QoS Selection Record
The practical workflow is to list each message family, decide what failure is tolerable, and record the protocol and application evidence that will prove the design works. A blanket "QoS 1 everywhere" or "QoS 2 for critical systems" rule hides too many edge cases.
For each row, include the retry horizon and the application outcome. A QoS 1 command with a command id and final state readback can be safer than a QoS 2 toggle with no idempotency. A retained status message may need QoS 1 when subscribers depend on it after reconnect, while a high-rate diagnostic stream may stay QoS 0. The record should also name what the broker is allowed to queue for offline subscribers and how long stale messages remain useful.
Fleet Selection Record
set_fan_state=on.Practitioner Checks
Separate protocol delivery from outcome
MQTT QoS proves a broker/client delivery step. It does not prove that a pump started, a door locked, or a technician responded.
Design for duplicates
QoS 1 is common in production because duplicates can be handled with event IDs, desired-state commands, and idempotent consumers.
Review offline behavior
Persistent sessions, retained state, broker limits, and client reconnect behavior decide what happens while subscribers are offline.
Practitioner Knowledge Check
The selection record should end with a test plan: disconnect a client, drop an acknowledgement, replay a duplicate, restart a subscriber, and verify that the application outcome still matches the message-family promise.
7.4 QoS Is Hop-by-Hop State
MQTT QoS is negotiated and enforced on each delivery leg. A publisher can send to the broker at one QoS, while a subscriber receives at a different effective QoS depending on its subscription and broker behavior. The broker is not just forwarding bytes; it may store state, retry, downgrade delivery, or queue messages for a persistent session.
This is why QoS should not be described as end-to-end business confirmation. A broker acknowledgement is not the same as application handling. Critical workflows still need an application-level acknowledgement, audit record, or state readback.
One practical test is to drop the network after each acknowledgement boundary and inspect what happens on reconnect. For QoS 1, the duplicate path should be visible through the DUP flag and through application deduplication logs. For QoS 2, the broker and client should resume the packet-id handshake instead of executing the action twice. Those traces make the distinction between protocol delivery and physical outcome concrete.
Sequence Views
What the Broker Must Remember
- QoS 0: the broker routes the message to current matching subscribers, but there is no acknowledgement state for that publish.
- QoS 1: the sender and receiver track a packet identifier until acknowledgement, and the receiver must handle possible redelivery.
- QoS 2: both sides track a handshake until completion, which reduces duplicate protocol delivery but increases state and timing sensitivity.
- Persistent sessions: offline behavior depends on session configuration, queued-message policy, retained messages, and broker limits, not just the publish QoS.
- Application outcomes: a device should publish a separate result or state update when the business outcome matters.
Bex’s Topic Board
- Topic: one topic, many strengths — each subscription sets its own effective QoS.
- QoS: QoS 1 holds a packet identifier until acknowledged; QoS 2 keeps a two-sided handshake open.
- Subscriber: a persistent session queues messages for an offline subscriber — within broker limits, silence costs storage.
For a critical command, a strong evidence chain has two acknowledgements: MQTT-level delivery to the broker path, and application-level proof that the device accepted or rejected the requested state.
Under-the-Hood Knowledge Check
The under-the-hood review is complete when you can explain what state exists at the publisher, broker, subscriber, and application outcome boundary for each message family.
7.5 Summary
MQTT QoS levels are delivery contracts, not global device quality settings. QoS 0 minimizes acknowledgement overhead for replaceable telemetry. QoS 1 adds delivery acknowledgement but requires duplicate-safe consumers. QoS 2 adds a stronger protocol handshake for narrow cases where duplicate protocol delivery is unsafe.
The most reliable design is usually a mix: QoS 0 for frequent state, QoS 1 for important events and idempotent commands, and application-level acknowledgement wherever a physical or business outcome must be proven.
7.6 Key Takeaway
Choose MQTT QoS per message family, then prove the outcome separately. Broker delivery evidence is useful, but it is not the same as device action, human response, or business completion.