Selecting MQTT QoS Levels in Node-RED for Reliable IoT Messaging
Guidance on choosing QoS 0, 1, or 2 in Node-RED MQTT nodes, with trade‑offs, a comparison table, and a function‑node example for per‑message QoS override.
02 Jun 2026, 12:33 UTC

When building IoT workflows in Node-RED, choosing the wrong MQTT Quality of Service (QoS) level can cause lost alerts or duplicate processing that corrupts data. This guide helps you decide which QoS level fits your reliability needs.
Decision and Constraints
First, identify the criticality of the data and the network characteristics:
- Is losing a message acceptable?
- Can your downstream logic handle duplicate messages safely?
- What is the expected latency tolerance?
Comparison of MQTT QoS Levels
| QoS Level | Guarantee | Overhead | Typical Use Case |
|---|---|---|---|
| 0 (At most once) | Fire‑and‑forget; no acknowledgment. | Lowest | High‑frequency sensor telemetry where occasional loss is tolerable. |
| 1 (At least once) | Guaranteed delivery via PUBACK; duplicates possible. | Medium | Status updates, alerts, and non‑critical commands. |
| 2 (Exactly once) | Guaranteed delivery via four‑phase handshake. | Highest | Critical control actions such as unlocking a gate or changing a device state. |
Trade‑offs
QoS 0 minimizes network traffic but offers no reliability; use only for data streams where a missing sample does not affect analysis.
QoS 1 provides a good balance: the broker acknowledges receipt, and Node‑RED will resend until an ACK arrives. Your flow must be idempotent—processing the same message twice must not produce incorrect results (e.g., avoid incrementing a counter on duplicate messages).
QoS 2 eliminates duplicates with a four‑step handshake, but adds latency and bandwidth consumption. Reserve it for actions where a duplicate execution would be unsafe.
Implementation: Setting QoS per Message
Node‑RED allows a global QoS setting in the MQTT out node, but you can override it per message by setting msg.qos in a Function node placed before the MQTT out node.
// Example: send QoS 1 for alert messages, QoS 2 for control commands
if (msg.topic === "home/alert") {
msg.qos = 1;
} else if (msg.topic === "home/gate/command") {
msg.qos = 2;
} else {
msg.qos = 0; // default for telemetry
}
return msg;
Verification and Testing
To confirm that Node‑RED is publishing at the intended QoS, use an external MQTT client such as mosquitto_sub. The Node‑RED debug pane shows the internal message but not the wire‑level QoS.
Run the following command, replacing placeholders with your broker address and topic:
mosquitto_sub -h -t "" -v
The output will prefix each received line with the QoS level (e.g., 1 home/alert payload). If you see a different number than expected, check the Function node logic or the MQTT out node’s default QoS setting.
Limitations
- QoS 1 and 2 require the MQTT client’s “Clean Session” flag to be false if you want the broker to queue messages while the client is disconnected.
- QoS 2 can become a bottleneck on low‑bandwidth or high‑latency links (e.g., cellular) due to the extra handshake packets.
- Retained messages persist until explicitly cleared; stale retained data can mislead new subscribers.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.