Skip to content
Stand with Ukraine flag

Delivery guarantees

MQTT Quality of Service (QoS) defines the delivery contract between sender and receiver for each message. It answers one question: what guarantee does the sender need that the receiver got the message? Three levels are available — each a trade-off between reliability and the number of network round trips required.

Choosing the right level matters because the wrong choice in either direction has a cost: QoS 0 loses messages on unreliable links; QoS 2 adds four-packet overhead to every message and can become a bottleneck at high throughput. Most IoT deployments use QoS 1 as the default and reserve QoS 2 for the small subset of messages where duplicate processing would cause real harm.

QoS 0QoS 1QoS 2
GuaranteeAt most onceAt least onceExactly once
DeliveryBest-effortGuaranteedGuaranteed
Duplicates possibleNoYesNo
Packets124
Relative overheadLowestMediumHighest
Offline queuingNoYes (persistent session)Yes (persistent session)

The message is sent once with no acknowledgement. If the network drops the packet, it is lost.

The sender removes the message from its queue immediately after sending. No retry, no confirmation.

Use when: message loss is acceptable and recency matters more than completeness. Typical examples: high-frequency sensor readings where the next value will arrive within seconds, UI state broadcasts, or metrics where an occasional gap is tolerable.

The message is delivered at least once. The sender retransmits until it receives a PUBACK.

If the PUBACK is lost in transit, the sender retransmits with the DUP flag set. The receiver may therefore process the same message more than once, so consumers must be idempotent — able to handle duplicates safely.

Use when: every message must arrive, and your processing logic can tolerate or deduplicate repeated delivery. Typical examples: telemetry from vehicles, security alerts, device state changes.

The message is delivered exactly once through a four-packet handshake that prevents both loss and duplication.

Neither side may reuse the packet ID until the full handshake completes. This is what guarantees exactly-once delivery: the receiver will not process the message until step 3 (PUBREL), and both sides persist enough state to resume after a crash.

Use when: duplicate processing causes real harm. Typical examples: financial transactions, actuation commands on industrial machinery, billing events.

When the publisher’s QoS and the subscriber’s QoS differ, TBMQ delivers the message at the lower of the two levels.

This means a QoS 2 subscription does not guarantee exactly-once delivery if the publisher sends at QoS 0 or QoS 1. Design for the actual delivered level, not the subscribed level.

QoS 1 and QoS 2 messages are only queued for offline clients when the subscriber uses a persistent session. With a non-persistent (clean) session, undelivered messages are discarded on disconnect regardless of QoS.

Session typeQoS 0QoS 1 / QoS 2
Non-persistentDiscarded on disconnectDiscarded on disconnect
PersistentDiscarded on disconnectQueued, delivered on reconnect

For QoS 0 specifically, the broker never queues messages — even in a persistent session.

For details on how TBMQ stores queued messages per client type, see Sessions.

SituationRecommended level
High-frequency sensor data; loss of one reading is harmlessQoS 0
Device telemetry that must reach the backendQoS 1
Commands sent to a device (on/off, setpoint)QoS 1 with idempotent handling
Financial or billing eventsQoS 2
Industrial actuation where duplicate execution causes damageQoS 2
Analytics consumer that must process every event exactly onceQoS 2 (publisher and subscriber)