MQTT Deep Dive: From Pub/Sub to QoS Levels
2026.09.22
Share on:
返回列表

In our previous article "MQTT Protocol in IoT Sensor Applications," we covered the basics of MQTT as a lightweight IoT messaging protocol. But to truly master MQTT in building automation and energy monitoring projects, knowing how to "connect, publish, and subscribe" is not enough. How should topic hierarchies be designed? How do you choose QoS levels? Will data be lost during reconnections? This article dives into MQTT's communication core—from the publish/subscribe model and QoS mechanisms to session management and protocol evolution—clarifying the key engineering decisions that determine project success.

1. The Pub/Sub Model: More Than Just "Decoupling"

At MQTT's heart lies the publish/subscribe model. Unlike Modbus's request/response or BACnet's object orientation, Pub/Sub introduces a critical intermediary—the message broker. Publishers and subscribers never communicate directly; instead, they interact through logical channels called "topics." A temperature sensor publishes to `building/floor3/room302/temperature`, and an energy platform subscribing to `building/floor3/#` receives temperature data from every room on that floor.

This architecture delivers three structural advantages for building IoT:

  • Spatial decoupling: Sensors and platforms need not know each other's IP addresses or network locations. Sensors don't even need fixed IPs—critical for field devices on NB-IoT or 4G Cat.1 carrier networks.

  • Temporal decoupling: While subscribers are offline, the broker can buffer messages (with persistent sessions and QoS≥1), so devices receive missed critical data upon reconnection.

  • Synchronous decoupling: Publishing is non-blocking. A sensor samples, publishes, and immediately returns to sleep without waiting for platform acknowledgment—translating to significant power savings for battery-powered devices.

The Engineering Craft of Topic Design

Topics are the "data schema" of an MQTT system; their design quality directly determines long-term maintainability. Three principles govern practice:

  • Hierarchical semantics: `campus/building/floor/room/parameter-type`, progressing from coarse to fine granularity left to right. Avoid meaningless names like `sensor001`—three months later, nobody remembers what it measures.

  • Judicious wildcard use: The single-level wildcard `+` matches one level (e.g., `building/+/temperature` gets temperatures from all floors), while the multi-level wildcard `#` matches all remaining levels (e.g., `building/#` gets everything in the building). Note: wildcards work only in subscriptions, never in publications.

  • Limit hierarchy depth: Topics deeper than seven levels increase broker matching overhead and operational complexity; keep within five levels.

A common anti-pattern is embedding device serial numbers in topics (e.g., `building/floor3/room302/SN123456/temperature`)—when the sensor fails and is replaced, subscriber logic must change accordingly. The correct approach: topics express "location and semantics"; device identity belongs in the message payload or client ID.

2. QoS Levels: Three Gears of Reliability

QoS (Quality of Service) is MQTT's most core—and most frequently misused—mechanism. It defines the reliable delivery level of messages from publisher to subscriber, in three tiers:

QoS LevelNameSemanticsTransmission CostTypical Scenarios
0At most onceFire and forget; no acknowledgment, no retransmission1 PUBLISHHigh-frequency periodic telemetry: second-level temperature sampling, heartbeat packets
1At least onceMust arrive; retransmit if unacknowledged; possible duplicates1 PUBLISH + 1 PUBACKEnergy metering data, alarm events, control commands
2Exactly onceStrictly once; four-way handshake deduplication4 messages (PUBLISH/PUBREC/PUBREL/PUBCOMP)Billing-grade data, critical device remote configuration

QoS 0: Fast, but Accept Loss

QoS 0 sends without any acknowledgment. Network glitches, broker overload, offline subscribers—all silently drop messages. But that doesn't render it useless: for second-level temperature/humidity reporting, losing one frame is inconsequential; the next arrives shortly. The engineering golden rule: use QoS 0 for high-frequency periodic data; guarantee quality through "data freshness" rather than "per-frame reliability."

QoS 1: Retransmission and the Deduplication Burden

QoS 1 requires the publisher to receive a PUBACK; it retransmits on timeout. The cost is possible duplicate delivery—network jitter may cause the same frame to arrive twice. Therefore, using QoS 1 presumes idempotent consumption: carry a message ID or timestamp in the payload, and subscribers deduplicate accordingly. Energy metering demands particular attention: duplicated meter readings accumulating will corrupt billing calculations.

QoS 2: When Four Times the Overhead Is Worth It

QoS 2 ensures exactly-once delivery through the PUBLISH→PUBREC→PUBREL→PUBCOMP handshake. But in building automation practice, its applicable scenarios are far fewer than imagined—most control commands, paired with business-layer state readback and timeout retry, work fine with QoS 1. QoS 2's legitimate scenarios: transactional data across systems (such as demand-response load adjustment settlements) and remote parameter pushes where repeated execution has side effects.

Key Insight: QoS Is a Per-Hop Promise, Not End-to-End

MQTT's QoS operates on each hop, not the entire end-to-end path. Publisher-to-broker is one hop; broker-to-subscriber is another. This means: even if the publisher sends at QoS 2, if the subscriber subscribes at QoS 0, the broker-to-subscriber hop can still lose messages. End-to-end reliability requires the minimum of the three parties' QoS levels, supplemented by application-layer acknowledgment as a safety net.

3. Sessions, Retained Messages, and Wills: The Complete Picture of Disconnection Handling

Clean Session and Persistent Sessions

In MQTT 3.1.1, the Clean Session flag determines session persistence: set to 1, the session burns on disconnect—the broker discards all subscriptions and undelivered messages; set to 0, the broker retains subscriptions and in-flight QoS 1/2 messages while the client is offline, delivering them upon reconnection. Resident subscribers like energy platforms should use persistent sessions—during a platform's nightly restart for upgrades, field sensor data queues at the broker and is automatically backfilled after recovery, avoiding monitoring gaps.

Retained Messages: The "Bulletin Board" of Latest Values

The broker keeps the last retained message per topic, delivering it immediately to new subscribers. This is extremely practical for platform-side logic: after startup, the platform instantly has the latest state across the network without waiting for the next report from each sensor. Engineering convention: publish "online status," "current readings," and "configuration versions"—data that latecomers need to know immediately—with the retained flag; flow-type data (frame-by-frame telemetry) should not be retained, lest new subscribers receive a pile of stale historical frames.

LWT: The Last Line of Defense for Offline Notification

The Last Will and Testament is pre-set at connection establishment: if the broker detects abnormal client disconnection (anything but an active DISCONNECT), it automatically publishes the will on the client's behalf. A canonical pattern is the device status topic `device/xxx/status`: a device publishes "online" (retained) upon connecting, with a pre-set will of "offline"—whatever the cause of disconnection, the broker automatically flips the status to offline, and the platform perceives the loss immediately instead of waiting 1.5× the keep-alive interval. Recommended: set keep-alive to one-third of the tolerable detection delay.

4. From 3.1.1 to 5.0: Engineering Dividends from Protocol Evolution

MQTT 5.0 (published 2019), while keeping the packet skeleton compatible, filled critical gaps for large-scale commercial deployments:

  • Reason Codes: In the 3.1.1 era, subscription failures and rejected publications could only be hinted through connection drops; 5.0 attaches reason codes to every acknowledgment, distinguishing "no permission" from "illegal topic" when subscriptions are refused—multiplied troubleshooting efficiency.

  • Message Expiry: Sets TTLs for retained and queued QoS messages, preventing stale data from being misinterpreted as real-time values after reconnection—in building data, the CO₂ concentration from ten minutes ago no longer has control value.

  • Shared Subscriptions: `$share/group1/building/#` lets multiple platform instances in the same group round-robin consume from one topic, achieving subscriber-side load balancing and high availability—the standard approach when horizontally scaling energy platforms.

  • User Properties: Message headers can carry key-value metadata (such as source gateway ID, quality bits) without invading payload formats.

  • Flow Control (Receive Maximum): Publishers can declare an upper limit on unacknowledged in-flight messages, allowing the broker to throttle and preventing slow consumers from being overwhelmed.

For greenfield projects, adopt MQTT 5.0 directly—mainstream brokers (EMQX, Mosquitto 2.x, HiveMQ) and client libraries (Paho, MQTT.js) all support it maturely. Existing 3.1.1 systems can upgrade the broker first to gain 5.0 server-side capabilities without changing device-side protocols.

5. Engineering Practice Essentials

  1. Broker selection and deployment: Small and medium projects are well served by Mosquitto (single node handles tens of thousands of connections); multi-campus, hundred-thousand-device deployments choose clustered solutions like EMQX. In production, always enable authentication (username/password or X.509 client certificates) and TLS encryption—expose port 8883 externally, keep 1883 internal-only.

  2. QoS selection decision tree: periodic telemetry → QoS 0; metering and alarms → QoS 1 + idempotent consumers; side-effect operations → QoS 2. Always ask "what happens if this message is lost?" rather than defaulting to the highest level.

  3. Topic governance upfront: Define topic conventions at project kickoff, document them, and reserve hierarchy expansion positions (e.g., `building/{id}/floor/{n}/...`) to avoid rework after delivery.

  4. Monitor the broker itself: The broker is the system's throat—monitor connection counts, message rates, and backlog queues. EMQX provides Prometheus metrics; simple projects can self-collect via the `$SYS/#` system topics.

  5. Boundary with BACnet/Modbus: MQTT does not replace field control protocols. The sensor-to-gateway segment still carries real-time closed-loop control via Modbus/BACnet; MQTT handles gateway-to-platform uplink aggregation and cloud distribution, with protocol conversion at the gateway—currently the most robust layered architecture for building IoT.

Conclusion

MQTT's elegance lies in supporting complex distributed communication needs with a minimalist packet skeleton. But a "simple protocol" does not mean "simple engineering": topic design determines the organizational capability of data assets; QoS selection reflects understanding of business reliability; session and will mechanisms preserve system dignity during disconnections. Mastering these internal mechanisms is what allows MQTT to truly become the data nerve of building automation and energy monitoring systems—both lightweight and resilient.