MQTT QoS Levels Explained: When to Use QoS 0, 1, or 2
MQTT's Quality of Service (QoS) levels are the mechanism that controls message delivery reliability. With three levels — QoS 0, QoS 1, and QoS 2 — MQTT lets you trade reliability for performance on a per-message basis. Choosing the wrong QoS level causes either lost messages or unnecessary network overhead. Whether you are setting up a local broker for device testing or building an industrial IoT pipeline, understanding QoS is essential. Here is how each level works and when to use it.
How MQTT QoS Works
QoS is negotiated between the sender (publisher or broker) and the receiver (subscriber or broker). Each message has a QoS level set by the publisher. The broker delivers the message to subscribers at the subscribed QoS level or lower — the lower of the two wins. This means if you publish at QoS 2 but a subscriber subscribed at QoS 0, the broker delivers at QoS 0.
There are two delivery hops in MQTT:
- Publisher → Broker: The publisher sends the message to the broker at the specified QoS.
- Broker → Subscriber: The broker forwards the message to each subscriber at the subscribed QoS (or the published QoS, whichever is lower).
Each hop is independent. A message published at QoS 2 might be delivered to one subscriber at QoS 2 and to another at QoS 0, depending on their subscription levels.
QoS 0: At Most Once
The publisher sends the message once. No acknowledgment. No retry. If the network drops the packet, the message is lost. The broker does not store it, and the subscriber never sees it.
Flow
Publisher sends PUBLISH → Broker receives and forwards → Done. Fire and forget.
When to Use QoS 0
- Sensor data that is updated frequently. Temperature readings every 5 seconds, ambient light levels, humidity. If one reading is lost, the next one arrives 5 seconds later. No harm done.
- High-frequency telemetry. GPS coordinates from a fleet tracker updating at 1 Hz. One missed position update is irrelevant — the next one corrects it immediately.
- Status broadcasts. "I am alive" heartbeat messages. The next heartbeat in 30 seconds renders the lost one irrelevant.
- Bandwidth-constrained networks. On satellite links or low-bandwidth cellular connections, QoS 0 minimizes overhead — no ACK packets, no retransmissions.
QoS 1: At Least Once
The publisher sends the message and waits for a PUBACK from the broker. If no acknowledgment arrives within the timeout, the publisher resends the message. This guarantees delivery — but the message might arrive more than once.
Flow
Publisher sends PUBLISH (Packet ID: 42) → Broker receives, stores, sends PUBACK (42) → Publisher receives PUBACK → Done. If PUBACK is lost, publisher resends PUBLISH with the same Packet ID. The broker may deliver both copies to subscribers.
The Duplicate Problem
QoS 1 guarantees at least once delivery, which means duplicates are possible. Your application must handle this. Common strategies:
- Idempotent operations: "Set temperature to 22°C" is idempotent — receiving it twice has the same effect as once.
- Timestamp-based deduplication: Ignore messages with timestamps older than the last processed message.
- Sequence numbers: Track the last sequence number processed and ignore any that are not strictly increasing.
When to Use QoS 1
- Alarm and event notifications. "Motor overload detected" or "Tank level below threshold" — these must be delivered. A duplicate alarm is annoying but not harmful.
- Configuration commands. "Set setpoint to 75.0" — duplicates are harmless for idempotent values.
- Most industrial IoT data. QoS 1 is the default choice for 90% of industrial MQTT deployments. It provides delivery guarantee with minimal overhead.
QoS 2: Exactly Once
QoS 2 uses a four-part handshake to guarantee that the message is delivered exactly once — no duplicates, no losses. This is the most reliable and most expensive QoS level.
Flow
Publisher sends PUBLISH (Packet ID: 42) → Broker receives, sends PUBREC (42) → Publisher sends PUBREL (42) → Broker releases to subscribers, sends PUBCOMP (42) → Done.
The Overhead Cost
QoS 2 requires four packets for every message (PUBLISH, PUBREC, PUBREL, PUBCOMP) compared to one for QoS 0 and two for QoS 1. This doubles the network traffic and increases latency. On constrained networks, QoS 2 can significantly reduce throughput.
When to Use QoS 2
- Billing and metering data. Energy consumption readings that determine customer invoices. A duplicate reading means double-charging a customer. A lost reading means revenue loss. Exactly-once is required.
- Financial transactions. Payment confirmations, order submissions, trade executions. Duplicates have real monetary consequences.
- Critical safety commands. Emergency shutdown signals where both loss and duplication could cause issues.
Quick Comparison
QoS 2 adds exactly-once delivery at the cost of 4 packets per message. Reserve it for scenarios where duplicates have real consequences.
Retained Messages and Last Will
Two MQTT features interact with QoS:
- Retained messages: The broker stores the last message published on a topic with the retain flag set. New subscribers receive this stored message immediately upon subscribing. Useful for "last known good" state — current temperature, latest setpoint, connection status. The retained message uses the QoS it was published with.
- Last Will and Testament (LWT): The broker publishes a pre-configured message if a client disconnects ungracefully. The LWT message has its own QoS level. For "device offline" notifications, QoS 1 ensures the will is delivered even if the network is unstable at the moment of disconnection.
Frequently Asked Questions
What is the difference between MQTT QoS 0, 1, and 2?
QoS 0 delivers a message at most once with no acknowledgment (fire and forget). QoS 1 delivers at least once with a PUBACK acknowledgment, meaning duplicates are possible. QoS 2 delivers exactly once using a four-part handshake (PUBLISH, PUBREC, PUBREL, PUBCOMP), which guarantees no duplicates and no losses but adds the most overhead.
Which MQTT QoS level should I use for IoT sensors?
For high-frequency sensor data like temperature or humidity readings updated every few seconds, QoS 0 is sufficient since a lost reading is quickly replaced by the next one. For alarms, event notifications, or commands that must be delivered, use QoS 1. Reserve QoS 2 for billing or metering data where duplicates have financial consequences.
Does MQTT QoS 1 cause duplicate messages?
Yes. QoS 1 guarantees at-least-once delivery, which means the broker may deliver the same message more than once if the PUBACK is lost and the publisher resends. Your application should handle duplicates through idempotent operations, timestamp-based deduplication, or sequence numbers.
When should I use MQTT QoS 2?
Use QoS 2 only when both message loss and duplication have serious consequences. Common use cases include energy metering data that determines customer invoices, financial transactions, and critical safety commands. QoS 2 requires four packets per message (double the overhead of QoS 1), so reserve it for scenarios where the cost of duplicates outweighs the bandwidth cost.
MQTT Client for macOS
MacTools MQTT Client — built-in broker, publish/subscribe, topic tree browser, message history. QoS 0, 1, and 2 all supported. No Homebrew, no CLI. $9.99 one-time.
Get MacTools MQTT ClientRelated: Full SCADA System
Need continuous MQTT monitoring with dashboards, alarms, and trending? Voltrus SCADA supports MQTT, Modbus TCP/RTU, OPC-UA, Siemens S7, BACnet, DNP3, and more. Lifetime license from $249.