Why MQTT Instead of HTTP?
HTTP is the most widely deployed application protocol on the internet, but it was designed for human-scale web browsing, not for millions of battery-powered sensors publishing small measurements continuously. HTTP's request/response model requires the client to initiate every exchange — to receive new data, a device must poll the server repeatedly, opening a new TCP connection, sending a request with hundreds of bytes of headers, and waiting for a response. For a temperature sensor publishing one reading every 30 seconds over a narrowband cellular link, this overhead is enormous relative to the payload size.
MQTT inverts this model. Devices maintain a single persistent TCP connection to a broker and publish data only when something changes or on a regular interval. The minimum MQTT fixed header is just 2 bytes. There is no polling and no repeated connection overhead. Subscribers receive messages pushed to them instantly without having to request them. For IoT deployments with thousands of devices on metered cellular connections, this difference translates directly into lower data costs, longer battery life, and reduced server load.
The Broker Model: No Direct Device-to-Device Communication
MQTT is built around a central broker. Publishers never send messages directly to subscribers — every message goes to the broker, and the broker distributes it to all clients that have subscribed to the relevant topic. This decoupling is fundamental to MQTT's design. Publishers do not need to know how many subscribers exist, their addresses, or whether any subscribers are currently online. Subscribers do not need to know which device published a message or where it is located on the network.
The broker maintains the subscription list, handles delivery acknowledgements, stores retained messages, and queues messages for temporarily offline subscribers. This centralised architecture simplifies device firmware significantly — a sensor needs only to know the broker's address and the topic to publish to. Adding a new data consumer (a dashboard, a database writer, an alerting service) requires zero changes to the sensor firmware: the new consumer simply subscribes to the relevant topics on the broker.
Topics and Wildcards
MQTT topics are hierarchical UTF-8 strings that organise the message space, similar to file system paths but using forward slashes as separators. A factory might structure its topics as factory/floor1/machine3/temperature or home/livingroom/thermostat/setpoint. Publishers specify the exact topic for each message. Subscribers can subscribe to exact topics or use wildcards to match multiple topics simultaneously.
The single-level wildcard + matches exactly one level in the hierarchy. A subscription to factory/+/machine3/temperature receives temperature messages from machine 3 on every floor. The multi-level wildcard # matches zero or more levels at the end of a topic string. A subscription to factory/# receives every message published under the factory hierarchy — useful for logging all factory telemetry to a time-series database. Wildcards can only be used in subscriptions, never in publish topics.
QoS Levels: Delivery Guarantees
MQTT defines three Quality of Service levels that trade delivery reliability against network overhead. QoS 0 (at most once) sends each message once with no acknowledgement. It is the fastest and lowest-overhead option — appropriate for high-frequency sensor readings where an occasional lost value is acceptable and retransmitting stale data would be counterproductive. QoS 1 (at least once) requires the broker to acknowledge each message with a PUBACK packet. The sender retransmits periodically until it receives the acknowledgement, guaranteeing delivery but potentially delivering duplicates if the acknowledgement is lost in transit.
QoS 2 (exactly once) uses a four-packet handshake to guarantee exactly one delivery with no duplicates: PUBLISH, PUBREC (broker acknowledges receipt), PUBREL (sender confirms it received PUBREC), PUBCOMP (broker confirms completion). This is the safest option for commands that must not be executed twice — turning a valve, charging a payment, unlocking a door — but it carries the highest latency and overhead. In practice, most IoT telemetry uses QoS 0 or 1; QoS 2 is reserved for command-and-control messages where duplicate execution would cause real-world harm.
Retained Messages and Last Will and Testament
Two MQTT features solve common IoT problems elegantly. Retained messages address the cold-start problem: when a new subscriber connects to a topic, it would normally have to wait for the next publish cycle before receiving any data. With retained messages, the publisher sets a retain flag on the message, and the broker stores the most recent retained message for that topic. Every new subscriber immediately receives the current value upon subscribing — essential for device status topics, configuration settings, and sensor readings where consumers need the current state right away.
The Last Will and Testament (LWT) feature lets devices declare an "I have died" message at connection time. When connecting to the broker, the device specifies a will topic, will payload, will QoS, and will retain flag. If the device disconnects uncleanly — a power failure, network drop, or firmware crash — the broker publishes the LWT message automatically. Other subscribers receive the LWT and know the device has gone offline without any heartbeat polling. A device can also connect with a clean DISCONNECT to suppress the LWT, signalling intentional shutdown rather than failure.
MQTT QoS Levels Compared
| QoS Level | Guarantee | Delivery | Handshake steps | Overhead | Best use case |
|---|---|---|---|---|---|
| QoS 0 | At most once | Fire and forget, no ACK | 1 (PUBLISH only) | Minimal | High-frequency sensor readings |
| QoS 1 | At least once | Retransmit until PUBACK | 2 (PUBLISH + PUBACK) | Low | Telemetry where loss is unacceptable |
| QoS 2 | Exactly once | Four-step handshake | 4 (PUBLISH / PUBREC / PUBREL / PUBCOMP) | High | Commands, actuators, payments |
MQTT Security
Out of the box, MQTT on port 1883 transmits all data including credentials in plaintext. Any observer on the network can read published messages and capture usernames and passwords. Production deployments must use MQTT over TLS on port 8883, which encrypts the entire connection including the CONNECT packet that carries credentials. TLS also enables mutual authentication: the broker presents a server certificate, and optionally each device presents a client certificate, allowing the broker to authenticate devices cryptographically rather than relying solely on username/password.
Beyond transport security, brokers implement access control lists (ACLs) that restrict which clients can publish or subscribe to which topics. A temperature sensor should be permitted to publish only to its own topic namespace, not to subscribe to command topics for other devices or to publish to a global broadcast topic. AWS IoT Core, HiveMQ, and most enterprise brokers enforce fine-grained per-client topic permissions. Username/password authentication using the MQTT CONNECT packet is the minimum baseline; certificate-based authentication is strongly recommended for production IoT deployments.
MQTT 5.0 Improvements
MQTT 5.0, published in 2019, added several significant features over the long-running 3.1.1 specification. Reason codes on all acknowledgement packets replace the limited success/failure feedback of earlier versions — a PUBACK can now carry a specific reason code explaining why a message was rejected. Message expiry intervals let publishers set a TTL on messages: if the broker cannot deliver a message within the specified interval, it discards it rather than delivering stale data to a subscriber that reconnected hours later. Shared subscriptions allow multiple subscribers to share a subscription on a topic, with the broker distributing messages round-robin among them — enabling load-balanced message processing across a pool of consumer instances without application-layer coordination. User properties attach arbitrary key-value metadata to any MQTT packet, enabling custom routing, tracing, and schema versioning without touching the payload.
MQTT Brokers and Ecosystem
Eclipse Mosquitto is the most widely deployed open-source MQTT broker. It is lightweight enough to run on a Raspberry Pi or even an OpenWrt router, making it the default choice for home automation projects and small-scale industrial deployments. HiveMQ is an enterprise broker with a clustering architecture that scales to millions of concurrent connections and provides a web-based management console, detailed monitoring, and a plugin API for custom extensions. AWS IoT Core is Amazon's managed MQTT broker that integrates directly with Lambda, DynamoDB, S3, and other AWS services — devices publish telemetry directly into cloud processing pipelines without managing any broker infrastructure.
On the client side, MQTT libraries exist for every major programming language and embedded platform: the Paho library (Eclipse Foundation) covers Python, Java, C, C++, Go, and JavaScript. Embedded MQTT clients exist for FreeRTOS, Arduino, and ESP-IDF (the ESP32 SDK). The Node-RED visual programming tool, widely used in home automation, treats MQTT as a first-class input and output node. Home Assistant, the dominant open-source home automation platform, uses MQTT as its primary device integration protocol through its MQTT Discovery feature, which lets devices announce their capabilities automatically without manual configuration.
Frequently Asked Questions
What is the difference between MQTT and HTTP for IoT?
HTTP uses a request/response model where each client must poll the server repeatedly to check for new data — each request carries a large header (typically 200–800 bytes) and opens a new connection. MQTT uses a persistent TCP connection and a publish/subscribe model: devices publish data to a broker when something changes, and subscribers receive it instantly without polling. MQTT's fixed header is just 2 bytes. For a temperature sensor publishing every 30 seconds over a constrained cellular link, MQTT uses a fraction of the data and battery that repeated HTTP polling would consume. HTTP is better for one-time requests to web APIs; MQTT is better for continuous, bidirectional IoT telemetry.
What is an MQTT broker?
An MQTT broker is the central server that receives all published messages and routes them to the appropriate subscribers. Publishers never send messages directly to subscribers — they always publish to the broker, which maintains a list of which clients have subscribed to which topics and forwards messages accordingly. The broker also stores retained messages, manages QoS delivery guarantees, handles Last Will and Testament messages, and enforces access control. Popular brokers include Eclipse Mosquitto (open-source, lightweight), HiveMQ (enterprise), and AWS IoT Core (managed cloud broker that scales to millions of devices).
What do MQTT QoS levels mean?
MQTT defines three Quality of Service levels. QoS 0 (at most once) sends the message once with no acknowledgement — the fastest and lowest overhead, but messages can be lost if the network drops. QoS 1 (at least once) requires the broker to acknowledge each message with a PUBACK; the sender retransmits until acknowledged, so the message is guaranteed to arrive but may be delivered more than once if the acknowledgement is lost. QoS 2 (exactly once) uses a four-step handshake (PUBLISH, PUBREC, PUBREL, PUBCOMP) to guarantee the message is delivered exactly once with no duplicates — the highest overhead but the strongest guarantee, used when duplicate processing would cause problems such as triggering an actuator twice.
What is a retained message in MQTT?
A retained message is a message published with the retain flag set to true. The broker stores the last retained message for each topic. When a new client subscribes to that topic, the broker immediately delivers the most recent retained message — even if it was published before the client connected. This solves a common IoT problem: a new subscriber would otherwise have to wait an unknown amount of time for the next publish cycle to receive the current state. Retained messages are ideal for device status, configuration values, and sensor readings where new subscribers need the current value immediately rather than waiting for the next update.
What port does MQTT use?
MQTT uses TCP port 1883 for unencrypted connections and port 8883 for MQTT over TLS (encrypted). Port 8883 is the standard for any production deployment where data confidentiality or device authentication matters. Brokers also commonly expose MQTT over WebSocket on port 443 or 8083, allowing browser-based clients and JavaScript applications to connect through firewalls that only permit HTTP/HTTPS traffic. For constrained environments where TLS overhead is genuinely too heavy, MQTT-SN (MQTT for Sensor Networks) is a variant designed to run over UDP on extremely low-power devices.
How does MQTT handle devices that go offline?
MQTT provides two mechanisms for offline resilience. The Last Will and Testament (LWT) feature lets a device register a message at connection time that the broker will publish automatically if the device disconnects unexpectedly without sending a proper DISCONNECT packet. Other subscribers receive the LWT message and know the device has gone offline. For QoS 1 and QoS 2 messages published to an offline subscriber, persistent sessions allow the broker to queue messages while the subscriber is disconnected and deliver them when it reconnects — provided the subscriber connected with the CleanSession flag set to false. This ensures no messages are lost during brief network outages on constrained devices.