
Introduction
In unstable network environments, using the TCP transport protocol, MQTT may face challenges in ensuring reliable communication. To address this issue, MQTT introduces a QoS mechanism that provides various message interaction options to meet specific requirements for reliable message delivery in different scenarios.
In this article, we will explore the QoS levels 0, 1, and 2 of MQTT, compare their performance, and provide practical use cases to help you decide the best option for your IoT project.
Introduction to MQTT QoS
QoS in MQTT refers to the level of guarantee for message delivery between the publisher and subscriber. It provides three service levels:
- QoS 0 – At Most Once Delivery
- QoS 1 – At Least Once Delivery
- QoS 2 – Exactly Once Delivery
With QoS 0, messages may be lost; with QoS 1, messages are guaranteed to be received, but they may be duplicated; with QoS 2, messages are guaranteed neither to be lost nor duplicated. The QoS levels from low to high not only indicate an increase in message reliability but also an increase in transmission complexity.
In a complete message delivery process from publisher to subscriber, the QoS level is specified by the publisher in the PUBLISH message. In most cases, the Broker maintains the original QoS when forwarding messages to subscribers. However, there are some exceptions where the QoS level of the message may be downgraded during forwarding based on the subscriber’s subscription requirements.
For example, if a subscriber requests that the maximum QoS level for messages forwarded by the Broker is QoS 1 during subscription, then all subsequent QoS 2 messages will be downgraded to QoS 1 when forwarded to this subscriber, while all QoS 0 and QoS 1 messages will maintain their original QoS levels during forwarding.

Next, let’s take a look at the specific principles of each QoS level in MQTT.
Detailed Explanation of MQTT QoS Levels
QoS 0 – At Most Once Delivery
QoS 0 is the lowest QoS level. QoS 0 messages are sent and forgotten, without waiting for acknowledgment, storage, or retransmission, so the receiver never needs to worry about receiving duplicate messages.

Why Do QoS 0 Messages Get Lost?
When we use QoS 0 to deliver messages, the reliability of messages entirely depends on the underlying TCP protocol.
TCP can only guarantee reliable arrival of messages as long as the connection is stable and not closed; once a connection is closed or reset, messages currently in the network link or the operating system’s buffer may still be lost. This is the primary scenario for QoS 0 message loss.
QoS 1 – At Least Once Delivery
To ensure message arrival, QoS 1 incorporates acknowledgment and retransmission mechanisms. The sender can only consider the message delivery successful after receiving the PUBACK message from the receiver; before that, the sender must store the PUBLISH message for retransmission.
QoS 1 requires setting a Packet ID in the PUBLISH message, and the responding PUBACK message will use the same Packet ID as the PUBLISH message, so that the sender can delete the correct PUBLISH message from its cache upon receipt.

Why Do QoS 1 Messages Get Duplicated?
For the sender, not receiving the PUBACK message can be categorized into two situations:
- The PUBLISH message did not reach the receiver
- The PUBLISH message has already reached the receiver, but the receiver’s PUBACK message has not yet reached the sender
In the first case, although the sender retransmits the PUBLISH message, the receiver still only actually receives the message once.
However, in the second case, during retransmission by the sender, the receiver has already received this PUBLISH message, leading to the receiver getting duplicate messages.

Even though the DUP flag in the PUBLISH message will be set to 1 during retransmission to indicate that this is a retransmitted message, the receiver cannot assume that it has previously received this message and must treat it as a new message.
This is because, for the receiver, the following two situations may exist:

In the first case, the sender retransmitted the PUBLISH message due to not receiving the PUBACK message. At this point, the two PUBLISH messages received by the receiver use the same Packet ID, and the second PUBLISH message has a DUP flag of 1, which indeed indicates that it is a duplicate message.
In the second case, the first PUBLISH message has completed delivery, and the Packet ID 1024 has become available again. The sender sends a brand new PUBLISH message using this Packet ID, but this time the message fails to reach the other end, so the sender subsequently retransmits this PUBLISH message. This means that although the second PUBLISH message received by the receiver also has the same Packet ID and DUP is 1, it is indeed a brand new message.
Since we cannot distinguish between these two situations, the receiver must treat all these PUBLISH messages as new messages. Therefore, when we use QoS 1, message duplication is unavoidable at the protocol level.
In extreme cases, for example, if the Broker receives duplicate PUBLISH messages from the publisher and retransmits them to the subscriber, retransmission may occur again, resulting in the subscriber ultimately receiving more duplicate messages.
In the example illustrated below, although the publisher’s intention was just to publish one message, the receiver ultimately received three identical messages:

This is the side effect of QoS 1 ensuring message delivery.
QoS 2 – Exactly Once Delivery
QoS 2 resolves the issues of message loss or duplication found in QoS 0 and 1, but correspondingly, it also brings the most complex interaction process and the highest overhead. Each QoS 2 message delivery requires at least two request/response processes between the sender and receiver.

- First, the sender stores and sends the PUBLISH message with QoS 2 to initiate the transmission of a QoS 2 message, then waits for the receiver to reply with a PUBREC message. This part is basically the same as QoS 1, except the response message changes from PUBACK to PUBREC.
- When the sender receives the PUBREC message, it can confirm that the other party has received the PUBLISH message, and the sender will no longer need to retransmit this message and also cannot retransmit this message. Therefore, at this point, the sender can delete the locally stored PUBLISH message and then send a PUBREL message to inform the other party that it is ready to mark the Packet ID used in this transmission as available. Like the PUBLISH message, we need to ensure that the PUBREL message reaches the other party, so a response message is also required, and this PUBREL message needs to be stored for subsequent retransmission.
- When the receiver receives the PUBREL message, it can confirm that there will be no retransmitted PUBLISH messages arriving during this transmission process, thus replying with a PUBCOMP message indicating that it is also ready to use the current Packet ID for new messages.
- When the sender receives the PUBCOMP message, this QoS 2 message transmission is officially completed. After this, the sender can use the current Packet ID again to send new messages, and when the receiver receives a PUBLISH message using this Packet ID again, it will treat it as a brand new message.
Why Do QoS 2 Messages Never Get Duplicated?
The logic for guaranteeing that QoS 2 messages are not lost is the same as for QoS 1, so we will not repeat it here.
Compared to QoS 1, QoS 2 introduces the PUBREL and PUBCOMP message processes, and it is this additional process that ensures messages are not duplicated.
Before we go further, let’s quickly review why QoS 1 messages cannot avoid duplication.
When we use QoS 1 messages, for the receiver, once the PUBACK response message is replied to, the Packet ID becomes available again, regardless of whether the response has actually reached the sender. Thus, it is impossible to know whether the subsequent arriving PUBLISH message with the same Packet ID was retransmitted by the sender due to not receiving the response or if the sender reused this Packet ID to send a brand new message after receiving the response.

Therefore, the key to message deduplication lies in how both parties communicate correctly to release the Packet ID, in other words, whether the sender retransmits a message or publishes a new message, there must be a consensus with the other party.
The PUBREL process added in QoS 2 provides the ability for both parties to negotiate when the Packet ID can be reused.

QoS 2 stipulates that the sender can only retransmit the PUBLISH message before receiving the PUBREC message. Once the PUBREC message is received and the PUBREL message is sent, the sender enters the Packet ID release process and cannot retransmit the PUBLISH message using the current Packet ID. At the same time, before receiving the PUBCOMP message confirming that both parties have completed the Packet ID release, the sender cannot use the current Packet ID to send new messages.

Therefore, for the receiver, it can use the PUBREL message as a boundary; any PUBLISH message arriving before the PUBREL message must be a duplicate message, while any PUBLISH message arriving after the PUBREL message must be a brand new message.
Once this premise is established, we can achieve message deduplication at the protocol level for QoS 2 messages.
Applicable Scenarios and Considerations for Different MQTT QoS Levels
QoS 0
The downside of QoS 0 is that messages may be lost, and the frequency of message loss depends on your network environment, which may cause you to miss messages during disconnection. However, the advantage is higher delivery efficiency.
Therefore, we typically choose to use QoS 0 for transmitting high-frequency and less important data, such as sensor data and periodic updates, where it is acceptable to miss a few cycles of data.
QoS 1
QoS 1 guarantees message arrival, making it suitable for transmitting more important data, such as issuing critical instructions or updating important status that requires real-time response.
However, since QoS 1 may also lead to message duplication, when we choose to use QoS 1, we also need to be able to handle message duplication or allow for message duplication.
Before we decide to use QoS 1 without deduplication processing, we need to understand what allowing message duplication may mean.
If we do not deduplicate QoS 1, we may encounter situations where the publisher publishes messages in the order of 1 and 2, but the subscriber ultimately receives messages in the order of 1, 2, 1, 2. If 1 represents a turn-on command and 2 represents a turn-off command, I think most users would not accept that they merely turned on and then turned off the light, resulting in the light flickering between on and off states.

QoS 2
QoS 2 guarantees both message arrival and that messages will not be duplicated, but it has the highest transmission cost. If we are unwilling to implement our own deduplication scheme and can accept the additional overhead brought by QoS 2, then QoS 2 will be a suitable choice. Typically, we see more use of QoS 2 in industries such as finance and aviation.