TL;DR:

  • MQTT’s publish/subscribe model decouples sensors from consumers — devices publish to topics, anything subscribed gets the message
  • QoS 0 is fire-and-forget; QoS 1 guarantees delivery at least once; QoS 2 guarantees exactly once at significant overhead cost
  • MQTT 5 adds critical features (reason codes, shared subscriptions, message expiry) that make it worth the migration for non-trivial deployments

MQTT (Message Queuing Telemetry Transport) became the dominant IoT messaging protocol not because it’s perfect, but because it makes the right tradeoffs: tiny footprint, designed for unreliable networks, and a clean publish/subscribe model that scales from two devices to millions. Understanding it properly — especially QoS semantics — prevents the class of bugs that silently drop sensor readings in production.

The Publish/Subscribe Model

MQTT’s core abstraction is a broker that sits between publishers and subscribers. Devices don’t send messages to each other directly — they publish to topics, and the broker routes messages to any client subscribed to matching topics.

Topics are hierarchical strings separated by /:

factory/line-1/sensor/temperature
factory/line-1/sensor/humidity
factory/line-2/sensor/temperature

Subscribers use wildcards: + matches one level (factory/+/sensor/temperature matches both lines), # matches all remaining levels (factory/line-1/# matches all sensors on line 1).

This decoupling is the protocol’s biggest advantage. A new analytics consumer subscribes to factory/# without touching a single device. When you’re adding monitoring to an existing deployment without modifying firmware, this matters enormously.

Retained messages let the broker store the last message on a topic. New subscribers immediately receive the last value rather than waiting for the next publish — critical for state topics like device configuration or last-known sensor readings.

QoS Levels

QoS (Quality of Service) controls delivery guarantees. Each message is published with a QoS level, and subscriptions declare a maximum QoS they’ll accept. The broker uses the lower of the two.

QoSDelivery GuaranteeHandshakeUse Case
0At most once (fire-and-forget)NoneHigh-frequency telemetry, acceptable data loss
1At least oncePUBACKCommands, alerts, data that must arrive
2Exactly oncePUBREC/PUBREL/PUBCOMPBilling events, control commands with side effects

QoS 0 is appropriate for temperature readings published every second — losing one sample occasionally doesn’t matter. QoS 1 is right for alarm conditions where duplicate delivery is acceptable but missing delivery is not. QoS 2 is rarely necessary and comes with a 4-packet handshake per message; use it only when duplicate processing would cause real harm (financial transactions, actuator commands that shouldn’t execute twice).

A common mistake is publishing everything at QoS 2 “to be safe.” On constrained hardware or cellular connections, the handshake overhead kills throughput and battery life. Match QoS to actual delivery requirements — don’t default to the highest level just because it sounds safer.

Choosing a Broker

BrokerBest ForClusteringCloud-Managed
MosquittoEmbedded, single-node, developmentNo (manual bridging)No
EMQXHigh-throughput production, analyticsYes (built-in)EMQX Cloud
HiveMQEnterprise, compliance, Java ecosystemYesHiveMQ Cloud
VernemqCarrier-grade, Erlang/OTP reliabilityYesNo
AWS IoT CoreAWS-native, managed, no opsManagedYes (AWS)

Mosquitto is the right starting point for most edge deployments — it’s a 200KB binary, runs on Raspberry Pi, and is trivially configured. For production deployments handling thousands of concurrent connections, EMQX is the current leader: it supports 100M+ concurrent connections per cluster, has a built-in rule engine for message transformation, and offers a Kubernetes operator for cloud deployments.

HiveMQ is the choice when compliance matters — financial services, healthcare, any regulated UK industry that needs audit logging and RBAC out of the box, with vendor support contracts for enterprise deployments.

MQTT 5 vs 3.1.1

MQTT 3.1.1 has been the dominant version since 2014. MQTT 5 (released 2019, now widely supported) fixes several limitations that hurt production deployments.

The most useful additions: reason codes on ACKs (3.1.1 returns only success/failure; MQTT 5 returns specific codes like “quota exceeded” or “topic alias invalid” that make debugging tractable), message expiry interval (stale commands are dropped before delivery, so a command queued during a reconnection gap doesn’t execute hours later), shared subscriptions (multiple consumers share a subscription group with round-robin distribution, so you can scale consumers horizontally without workarounds), and will delay interval (last-will messages can be delayed to avoid spurious disconnect alerts during brief network interruptions).

For new deployments, use MQTT 5. Most modern brokers (EMQX, HiveMQ, Mosquitto 2.x) and client libraries support it. The migration path from 3.1.1 is smooth since MQTT 5 brokers support both versions simultaneously.

MQTT vs HTTP vs CoAP

ProtocolOverheadDirectionConnectionBest For
MQTTLowBi-directionalPersistentMany devices, frequent messages
HTTP/RESTHighRequest/responsePer-requestLow-frequency, simple devices
CoAPVery lowRequest/responseUDP/DTLSConstrained MCUs, lossy networks

HTTP is simple and universally supported but requires a new TCP connection per request and has high overhead for small payloads. Fine for devices that report once per minute. CoAP is MQTT’s main competitor for constrained microcontrollers — it runs over UDP, has a tiny footprint, and supports observe patterns similar to pub/sub. Use CoAP when devices run on microcontrollers too small for a TCP stack; use MQTT for everything else.

The Bottom Line

MQTT is the right default for IoT messaging — the pub/sub model, QoS flexibility, and broker ecosystem are well-matched to the problem space. Spend time designing your topic hierarchy early: it’s difficult to restructure once devices are deployed. Use QoS 0 or 1 for most telemetry, migrate to MQTT 5 for new deployments, and start with Mosquitto before moving to EMQX when scale demands it.