Dev Station Technology

Mqtt quality of service qos

MQTT QoS: Understanding The 3 Levels Of Service

TL;DR

  • Definition. MQTT QoS defines the delivery guarantee between a publisher and broker across three levels: At most once (0), At least once (1), and Exactly once (2).
  • Trade-off. Each level increases reliability but also increases network overhead, latency, and power consumption — QoS 2 uses 4x the packets of QoS 0.
  • Most used. QoS 1 is the most common in production IoT systems, balancing guaranteed delivery with acceptable overhead.
  • Selection rule. Match QoS to data criticality: use QoS 0 for high-frequency telemetry, QoS 1 for commands and alerts, QoS 2 only for mission-critical transactions where duplicates cause harm.
  • Implementation. Set the qos parameter (0, 1, or 2) in your MQTT client library’s publish call — the handshake logic is handled automatically.

01 / 06

What Is MQTT QoS?

MQTT Quality of Service (QoS) is a delivery agreement between a message sender and the broker that defines how much effort both sides invest in ensuring a message arrives. It is the primary mechanism for controlling reliability versus performance in any MQTT-based IoT system.

Devices in IoT networks operate under unpredictable conditions — intermittent cellular coverage, congested Wi-Fi, and constrained battery life. MQTT was designed for these environments, and QoS is its core reliability control. The protocol offers exactly three levels, and every message is tagged with one of them. The level you choose directly impacts whether messages can be lost, duplicated, or delivered with absolute certainty.

QoS is negotiated independently for each publish operation. A publisher sets the QoS level on outbound messages, and a subscriber requests a QoS level when subscribing. The broker enforces the lower of the two, so a subscriber asking for QoS 1 receiving a QoS 2 publish will get QoS 1 delivery guarantees. This per-message granularity lets you mix reliability levels within a single application — sending sensor readings at QoS 0 while commanding actuators at QoS 1, for example.

3

QoS Levels Defined

1x – 4x

Packet Overhead Range

~85%

IoT Developers Using QoS 1+


02 / 06

The 3 MQTT QoS Levels Explained

Each QoS level defines a specific message handshake between client and broker. Higher levels add more round-trip packets to eliminate delivery failures, but at a direct cost to throughput, latency, and device battery life.

QoS 0 — At Most Once

Fire-and-forget delivery. The sender transmits a single PUBLISH packet and moves on immediately. No acknowledgment is expected or retransmission attempted. If the packet is lost, the message is simply gone.

Packet flow: PUBLISH → (1 packet, 1x baseline overhead)

Best for: High-frequency telemetry where individual readings are disposable — ambient temperature, humidity, air quality indexes reported every few seconds.

QoS 1 — At Least Once

Acknowledged delivery. The sender transmits PUBLISH with a Packet Identifier and stores the message until it receives a PUBACK from the broker. If the acknowledgment never arrives, the sender retransmits. This guarantees delivery but allows duplicates.

Packet flow: PUBLISH → ← PUBACK (2 packets, ~2x overhead)

Best for: Commands and alerts where delivery matters but duplicates are harmless — turning on a light, triggering a notification, updating a display state.

QoS 2 — Exactly Once

The highest assurance level. A four-part handshake eliminates both message loss and duplication. The sender publishes, the receiver acknowledges receipt (PUBREC), the sender releases (PUBREL), and the receiver confirms completion (PUBCOMP). Both sides maintain state throughout, so a lost packet at any stage triggers retransmission without risking a duplicate.

Packet flow: PUBLISH → ← PUBREC → PUBREL → ← PUBCOMP (4 packets, ~4x overhead)

Best for: Mission-critical transactions where duplicates cause real harm — financial operations, medication dispensing, robotic arm control, door-lock commands in security systems.


03 / 06

QoS Level Comparison

The following table maps each QoS level against the five dimensions that matter most when architecting an IoT messaging system: delivery guarantee, network overhead, latency, power consumption, and implementation complexity.

Dimension QoS 0: At Most Once QoS 1: At Least Once QoS 2: Exactly Once
Delivery Guarantee No guarantee — message may be lost Guaranteed at least once — duplicates possible Guaranteed exactly once — no loss, no duplicates
Packet Count 1 (PUBLISH only) 2 (PUBLISH + PUBACK) 4 (PUBLISH + PUBREC + PUBREL + PUBCOMP)
Relative Overhead 1x (baseline) ~2x ~4x
Latency Lowest — single one-way trip Medium — one round-trip for acknowledgment Highest — two full round-trips
Power Consumption Lowest Medium Highest — significant for battery-powered devices
Implementation Complexity Simplest — send and forget Requires duplicate handling (idempotent design) Most complex — both sides must track transaction state
Recovery on Failure None — message is gone Automatic retransmission until PUBACK received Automatic retransmission at any handshake stage

Key insight: Moving from QoS 0 to QoS 2 results in a 300% increase in network packets per message. For a battery-powered sensor sending 500 messages per day, this directly translates into measurably shorter field life — choose the lowest level that satisfies your reliability requirement.


04 / 06

When to Use Each QoS Level

There is no single best QoS level — only the right level for your specific data type, device constraints, and network conditions. The three factors below determine the optimal choice.

Choose QoS 0 When

Data is non-critical and frequently updated. Losing a single reading has no business impact because the next reading arrives within seconds. Devices are severely constrained (small battery, low bandwidth). Examples: ambient temperature telemetry, humidity reports, GPS pings on a moving vehicle, occupancy counts.

Choose QoS 1 When

Delivery must be confirmed, but a duplicate message causes no harm (the operation is idempotent). This covers the majority of IoT commands: set a relay to ON, update a thermostat setpoint, trigger an alert notification, log an event. QoS 1 is the most widely deployed level in production IoT systems.

Choose QoS 2 When

Both message loss and duplication are unacceptable. A duplicate financial transaction, a repeated medication dose, or a second unlock command on a security door could cause real damage. Reserve QoS 2 strictly for these mission-critical operations — its overhead makes it impractical for routine telemetry.

Network Conditions Matter

On stable wired or strong Wi-Fi networks, QoS 0 risks are lower. On cellular or LPWAN links with frequent dropouts, QoS 1+ retransmission becomes essential. Match the guarantee level to the network’s packet loss rate, not just the data’s business criticality.

Decision rule: If losing a message has no impact, use QoS 0. If losing a message is unacceptable but duplicates are harmless, use QoS 1. If duplicates would cause a system failure, use QoS 2.


05 / 06

Implementation and Best Practices

Implementing QoS in code is straightforward — set the qos parameter in your MQTT client’s publish call. The handshake logic is handled entirely by the library. Below is a practical reference using the Paho MQTT client for Python, followed by key practices for production systems.

Code Reference

import paho.mqtt.client as mqtt

client = mqtt.Client("publisher_id")
client.connect("broker.example.com", 1883)
client.loop_start()

QoS 0: high-frequency, non-critical telemetry

client.publish("iot/sensor/temperature", payload="23.5", qos=0)

QoS 1: command that must arrive (idempotent)

client.publish("iot/device/command", payload="TURN_ON", qos=1)

QoS 2: mission-critical transaction (exactly once)

client.publish("iot/system/payment", payload="TXN_12345", qos=2) client.loop_stop() client.disconnect()

Production Best Practices

  1. Design for idempotency at QoS 1. Since duplicates are possible, every subscriber receiving QoS 1 messages must handle them safely. Use unique message IDs or timestamps to deduplicate, or ensure the operation is naturally idempotent (setting a state to ON twice has the same result as setting it once).
  2. Set QoS per topic, not globally. Different data types within the same application have different reliability needs. Publish telemetry at QoS 0 and commands at QoS 1 on separate topics rather than applying one level to everything.
  3. Reserve QoS 2 sparingly. The four-packet handshake quadruples network traffic and CPU load. Use it only where the cost of a duplicate genuinely exceeds the overhead. Most production IoT systems run almost entirely on QoS 0 and 1.
  4. Use persistent sessions for QoS 1/2. Enable clean_session=False so the broker stores undelivered messages and pending acknowledgments across client reconnects. Without this, messages queued during an offline period are lost.
  5. Monitor duplicate rates as a network health signal. A rising duplicate rate at QoS 1 indicates PUBACK packets are being lost — a sign of network degradation. Use this metric to trigger alerts before message delivery is affected.

Warning: On battery-powered devices, QoS 2 can reduce operational life by 30–50% compared to QoS 0 for the same message volume. Always profile power consumption with your actual hardware and message frequency before committing to QoS 2 in production.


06 / 06

Next Steps

Applying the right QoS level is one of the highest-leverage architectural decisions in an IoT system — it affects reliability, latency, device battery life, and infrastructure costs simultaneously. The steps below give you a practical path from assessment to production.

  1. Audit your current message types. List every topic in your system and classify each as non-critical telemetry, important command, or mission-critical transaction. Assign QoS 0, 1, or 2 accordingly.
  2. Implement idempotent subscribers. For every topic at QoS 1, verify that duplicate messages cannot cause incorrect state. Add deduplication logic using message IDs or timestamps if the operation is not naturally idempotent.
  3. Enable persistent sessions. Set clean_session=False on devices that receive QoS 1 or 2 messages so the broker buffers messages during offline periods and resumes delivery on reconnect.
  4. Profile and optimize. Measure actual packet loss, duplicate rates, and battery impact on representative hardware. Adjust QoS levels down where the measured network reliability is higher than assumed.

Need help architecting your MQTT messaging layer? Dev Station Technology designs and builds production-grade IoT platforms — from protocol selection and QoS strategy to broker infrastructure and device firmware. Contact our team at sale@dev-station.tech for a technical consultation.

Serving Clients Across the US & UK

Dev Station Technology partners with startups, enterprises, and development teams throughout the United States and the United Kingdom. Our Vietnam-based engineering teams offer significant time-zone overlap with both US Eastern/Pacific and UK GMT business hours, ensuring real-time collaboration and faster delivery cycles. We bill in USD and GBP, comply with US regulations (SOC 2, HIPAA) and UK/EU standards (GDPR, ISO 27001), and provide dedicated account management for North American and British clients.

Ask an AI about this

Want an AI assistant to summarize or cite this guide?

Click any link below to open the AI with a pre-filled prompt referencing this article:

Ready to Build Your Field App?

Contact Dev Station Technology to discuss your project requirements and receive a development roadmap within 48 hours.

Get a Quote →

Related articles

Let's Talk