MQTT QoS Explained: Understanding QoS 0, 1, and 2
February 24, 2026

MQTT QoS Explained: Understanding QoS 0, 1, and 2
In the world of IoT, network conditions can be unpredictable. To ensure reliable messaging, the MQTT protocol includes a crucial feature called Quality of Service (QoS). QoS defines the guarantee of message delivery between a client and the MQTT broker.
Choosing the right QoS level is a critical design decision, as it involves a trade-off between reliability and overhead (latency, bandwidth, and device processing power).
QoS 0: At Most Once
This is the fastest and least reliable delivery method. The publisher sends the message once and does not wait for an acknowledgment. It's a "fire and forget" approach.
- Guarantee: The message is delivered at most once, or not at all.
- Use Case: Ideal for non-critical, high-frequency sensor data where losing an occasional message is acceptable. Think of an ESP32 temperature sensor reporting every second. If one reading is missed, the next one will arrive shortly.
QoS 1: At Least Once
This level guarantees that the message will be delivered at least once. The sender stores the message and re-sends it until it receives a PUBACK (Publish Acknowledgment) packet from the receiver.
- Possible Issue: The receiver might get the message, but the sender doesn't receive the acknowledgment. The sender then resends the message, leading to duplicates. The receiving application must be designed to handle this.
- Use Case: Good for important commands where you must ensure receipt, such as in a smart home system. For example, sending a command to turn a light on.
QoS 2: Exactly Once
This is the most reliable but slowest method. It uses a four-part handshake to ensure the message is delivered exactly once, which is a core part of the publish-subscribe model.
- Guarantee: The message is delivered exactly once. No loss, no duplicates.
- Use Case: Essential for critical systems where data integrity is paramount, such as in industrial messaging with Sparkplug B or financial transactions.
Choosing the Right QoS Level
| QoS Level | Guarantee | Duplicates Possible? | Overhead | Use Case |
|---|---|---|---|---|
| 0 | At Most Once | No | Lowest | Non-critical sensor data, telemetry |
| 1 | At Least Once | Yes | Medium | Commands, alerts, status updates |
| 2 | Exactly Once | No | Highest | Critical control, financial transactions |
In-Depth Analysis of Each QoS Level
To build robust and efficient IoT systems, a deeper understanding of the mechanics, trade-offs, and failure modes of each QoS level is essential. Let's dissect each one.
QoS 0: The Unconfirmed Service
QoS 0 operates on a best-effort basis. The publisher sends the PUBLISH packet and immediately moves on. It doesn’t use a Packet ID because there's no need to track the message.
Technical Flow:
- Publisher to Broker: The client sends the
PUBLISHpacket to the broker. The connection's underlying TCP/IP protocol provides a basic level of reliability, but it doesn't protect against all failure modes. - Broker to Subscriber: The broker receives the message and, for each matching subscriber that requested QoS 0, it sends the
PUBLISHpacket onward. It doesn't wait for any acknowledgment from the subscribers.
Failure Scenarios:
- If the TCP connection between the publisher and broker is broken after the client's OS has sent the packet but before the broker has fully received and processed it, the message is lost.
- If the broker fails or restarts after receiving the message but before delivering it to subscribers, the message is lost (unless the broker is configured for high availability with message syncing, which is an advanced topic).
- If the subscriber is temporarily disconnected, it will miss all QoS 0 messages published during its absence.
When is QoS 0 the Right Choice? The key principle for using QoS 0 is idempotency of data over time. This means that the value of a single message is low because a new, more current message will soon replace it.
- High-Frequency Telemetry: A sensor sending location data every second. Losing one point is irrelevant.
- Video or Audio Streams: In live streaming scenarios over MQTT, dropping a single frame (one message) is preferable to the latency and overhead of guaranteeing its delivery, which would cause buffering and jitter.
- Non-Critical Logging: Sending device health metrics where an occasional gap in data is acceptable.
QoS 0 Key Takeaway
Use QoS 0 when the data is high-volume and time-sensitive, and the loss of individual messages is less important than maintaining low latency and minimizing device/broker overhead. Never use it for commands or state changes that must be processed.
QoS 1: The Acknowledged Service
QoS 1 provides a guarantee that a message will be delivered, but it might be delivered more than once. This is the most common QoS level for general-purpose IoT applications.
Technical Flow & The Duplicate Problem:
The flow involves a two-part handshake: PUBLISH -> PUBACK.
- The Publisher assigns a Packet ID to the
PUBLISHpacket. - It sends the packet and stores a copy of it in an internal queue (often called "in-flight messages").
- The Broker receives the
PUBLISHpacket. It processes the message and sends aPUBACKpacket back to the publisher with the same Packet ID. - The Publisher receives the
PUBACK, matches the Packet ID, and deletes its stored copy of the message.
How Duplicates Happen:
The "at least once" guarantee stems from the publisher's retry mechanism. If the publisher does not receive a PUBACK within a certain timeout period, it assumes the message was lost and re-sends it with the same Packet ID and a special DUP (duplicate) flag set to true.
The classic scenario for duplication is:
- Publisher sends
PUBLISH. - Broker successfully receives
PUBLISH, processes it, and delivers it to subscribers. - Broker sends
PUBACK. - The
PUBACKpacket is lost on the network, or the publisher disconnects before receiving it. - The publisher reconnects, doesn't know the broker received the message, and resends the original
PUBLISHpacket. - The broker receives the duplicate message and processes it again, delivering it to subscribers a second time.
Designing for Duplicates (Idempotency): Your subscribing application must be designed to be idempotent when using QoS 1. This means that processing the same message multiple times should have the same effect as processing it just once.
- Use a Unique Message ID in the Payload: Include a unique identifier (like a UUID or a timestamp + device ID) within your JSON payload. The consumer can keep a short-term cache of recently processed message IDs and discard any duplicates it sees.
- State-Based Logic: If a command is "turn on light", the consumer's logic should first check "is the light already on?". If yes, it does nothing. This is inherently idempotent.
- Database UPSERT: When storing data, use an
UPSERT(update or insert) operation with a primary key based on the message's unique content, rather than a simpleINSERT.
When is QoS 1 the Right Choice?
- Commands: Turning a smart plug on or off. You need to know the command arrived. If it arrives twice, an idempotent consumer won't cause issues.
- Alerts: A smoke detector sending an "ALARM" message. You absolutely need this message to get through.
- Important State Changes: A user updating a setting on a device. The change must be applied.
QoS 2: The Assured Service
QoS 2 is the highest level of service, guaranteeing that a message is received and processed exactly once. It is the most robust but also the most resource-intensive.
Technical Flow: The Four-Part Handshake This handshake ensures that both the sender and receiver have a shared understanding of the message transfer state, eliminating duplicates.
PUBLISH: The publisher sends aPUBLISHpacket with a Packet ID and stores the message.PUBREC(Publish Received): The broker receives thePUBLISHpacket. It stores the message and the Packet ID, then responds with aPUBREC. ThisPUBRECtells the publisher, "I have received your message and have taken responsibility for it. Please don't send it again."PUBREL(Publish Release): Upon receiving thePUBREC, the publisher can finally discard its copy of the original message. It then sends aPUBRELpacket to the broker. This tells the broker, "I have received your confirmation. You are now free to complete the delivery."PUBCOMP(Publish Complete): The broker receives thePUBREL. It can now safely deliver the message to its subscribers and, once that is done, it can discard its stored state for that Packet ID. It sends a finalPUBCOMPpacket to the publisher to conclude the handshake.
Why is this so complex?
The extra PUBREL/PUBCOMP steps solve the QoS 1 duplication problem. In the QoS 1 scenario where the acknowledgment (PUBACK) is lost, the sender resends. In QoS 2, if the PUBREC is lost, the sender resends the PUBLISH. The broker, seeing the same Packet ID, doesn't re-process the message; it simply re-sends the PUBREC. The critical message delivery to subscribers only happens after the broker receives the PUBREL, confirming the publisher is aware the message has been secured.
Performance and Resource Implications:
- Latency: The round-trip time for a QoS 2 message is double that of QoS 1.
- Bandwidth: It requires two full round-trips of data exchange between the client and broker.
- State Management: Both the client and the broker must store the state of the message (the Packet ID and potentially the message itself) for a longer duration, increasing memory usage. This is a significant consideration for brokers handling thousands of clients and for memory-constrained devices.
When is QoS 2 the Right Choice? QoS 2 should be used sparingly and only when the business logic absolutely cannot tolerate duplicates and the potential for data loss is unacceptable.
- Billing Systems: An IoT device reporting usage for which a customer will be billed. A duplicate message could lead to double-charging; a lost message is lost revenue.
- Critical Remote Control: A command to a robotic arm in a manufacturing plant to perform an irreversible action. You must be certain the command is executed exactly once.
- Financial Transactions: Transferring funds or executing a trade based on an MQTT message.
The Interaction Between Publisher QoS and Subscriber QoS
A common point of confusion is how the QoS level set by the publisher interacts with the QoS level set by a subscriber.
The Rule of Downgrading: When an MQTT client subscribes to a topic, it specifies the maximum QoS level at which it wishes to receive messages. The broker is responsible for delivering the message according to this rule:
The effective QoS of a message delivered to a subscriber is the minimum of the message's original published QoS and the QoS level requested by the subscriber.
| Published QoS | Subscriber's Requested QoS | Effective QoS of Delivered Message |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 2 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
| 1 | 2 | 1 |
| 2 | 0 | 0 |
| 2 | 1 | 1 |
| 2 | 2 | 2 |
Example Scenario:
- An industrial sensor publishes a critical alert (
PUBLISHwith QoS 2). - A dashboard application, used for [real-time monitoring](/resources/real-time monitoring) where a missed alert is acceptable if a new one follows, subscribes with QoS 0. The broker will deliver the alert to the dashboard with QoS 0.
- A data archiving service, which must log every alert, subscribes with QoS 2. The broker will perform the full QoS 2 handshake with the archiver to ensure it receives the message exactly once.
This mechanism provides immense flexibility, allowing different consumers to use the same data stream according to their own reliability requirements without placing an unnecessary burden on every client.
QoS, Sessions, and Offline Reliability
Quality of Service works hand-in-hand with another MQTT feature: Persistent Sessions.
- Clean Session (
cleanSession = true): When a client connects with this flag, it starts fresh. The broker erases any previous information about the client. If the client disconnects, its subscriptions are removed, and any messages sent to it while offline are discarded. - Persistent Session (
cleanSession = false): When a client connects with this flag, the broker keeps its session information:- The client's subscriptions.
- All QoS 1 and QoS 2 messages that have been published to its subscribed topics while it was offline.
How it Works:
Imagine a smart home controller for your lights subscribes with QoS 1 and connects with cleanSession = false.
- The controller is running normally.
- You publish a command
home/lights/livingroom/setwith QoS 1. The broker delivers it. - The controller's Wi-Fi drops, and it disconnects.
- While it is offline, you publish another command
home/lights/livingroom/setwith QoS 1. - The broker sees that a persistent session client is subscribed to this topic and queues the message. It does not queue QoS 0 messages.
- When the controller reconnects later with the same
ClientIDandcleanSession = false, the broker immediately re-sends all the queued QoS 1 and QoS 2 messages.
This powerful combination is the key to building reliable systems that can survive network instability, ensuring that important commands and data are never lost just because a device was temporarily offline.