MQTT QoS Explained: Understanding QoS 0, 1, and 2

February 24, 2026

MQTT QoS Explained: Understanding QoS 0, 1, and 2

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.

sequenceDiagram participant P as Publisher participant B as Broker participant S as Subscriber P->>B: PUBLISH (QoS 0) Note over P,B: No confirmation sent B->>S: PUBLISH (QoS 0) Note over B,S: No confirmation sent
  • 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.

sequenceDiagram participant P as Publisher participant B as Broker P->>B: PUBLISH (QoS 1, Packet ID 123) Note over P: Store message until acknowledged B-->>P: PUBACK (Packet ID 123) Note over P: Discard stored message
  • 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.

sequenceDiagram participant P as Publisher participant B as Broker P->>B: PUBLISH (QoS 2, Packet ID 456) Note over P: Store message B-->>P: PUBREC (Packet ID 456) Note over B: Store message P->>B: PUBREL (Packet ID 456) Note over P: Discard message B-->>P: PUBCOMP (Packet ID 456) Note over B: Discard message, deliver to subscribers
  • 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 LevelGuaranteeDuplicates Possible?OverheadUse Case
0At Most OnceNoLowestNon-critical sensor data, telemetry
1At Least OnceYesMediumCommands, alerts, status updates
2Exactly OnceNoHighestCritical 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:

  1. Publisher to Broker: The client sends the PUBLISH packet 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.
  2. Broker to Subscriber: The broker receives the message and, for each matching subscriber that requested QoS 0, it sends the PUBLISH packet 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 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.

  1. The Publisher assigns a Packet ID to the PUBLISH packet.
  2. It sends the packet and stores a copy of it in an internal queue (often called "in-flight messages").
  3. The Broker receives the PUBLISH packet. It processes the message and sends a PUBACK packet back to the publisher with the same Packet ID.
  4. 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:

  1. Publisher sends PUBLISH.
  2. Broker successfully receives PUBLISH, processes it, and delivers it to subscribers.
  3. Broker sends PUBACK.
  4. The PUBACK packet is lost on the network, or the publisher disconnects before receiving it.
  5. The publisher reconnects, doesn't know the broker received the message, and resends the original PUBLISH packet.
  6. 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 simple INSERT.

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.

  1. PUBLISH: The publisher sends a PUBLISH packet with a Packet ID and stores the message.
  2. PUBREC (Publish Received): The broker receives the PUBLISH packet. It stores the message and the Packet ID, then responds with a PUBREC. This PUBREC tells the publisher, "I have received your message and have taken responsibility for it. Please don't send it again."
  3. PUBREL (Publish Release): Upon receiving the PUBREC, the publisher can finally discard its copy of the original message. It then sends a PUBREL packet to the broker. This tells the broker, "I have received your confirmation. You are now free to complete the delivery."
  4. PUBCOMP (Publish Complete): The broker receives the PUBREL. 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 final PUBCOMP packet to the publisher to conclude the handshake.
sequenceDiagram participant P as Publisher participant B as Broker P->>B: 1. PUBLISH (PacketID: 100) note right of P: State: Waiting for PUBREC note left of B: Action: Store message, send PUBREC B-->>P: 2. PUBREC (PacketID: 100) note right of P: State: Waiting for PUBCOMP<br/>Action: Discard original message, send PUBREL P->>B: 3. PUBREL (PacketID: 100) note left of B: Action: Discard stored message,<br/>deliver to subscribers,<br/>send PUBCOMP B-->>P: 4. PUBCOMP (PacketID: 100) note right of P: State: Handshake complete

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 QoSSubscriber's Requested QoSEffective QoS of Delivered Message
000
010
020
100
111
121
200
211
222

Example Scenario:

  • An industrial sensor publishes a critical alert (PUBLISH with 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:
    1. The client's subscriptions.
    2. 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.

  1. The controller is running normally.
  2. You publish a command home/lights/livingroom/set with QoS 1. The broker delivers it.
  3. The controller's Wi-Fi drops, and it disconnects.
  4. While it is offline, you publish another command home/lights/livingroom/set with QoS 1.
  5. The broker sees that a persistent session client is subscribed to this topic and queues the message. It does not queue QoS 0 messages.
  6. When the controller reconnects later with the same ClientID and cleanSession = 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.



Frequently Asked Questions (FAQ)