MQTT is a lightweight publish-subscribe protocol designed to move messages between clients through a broker. Its small wire format matters, but the protocol's larger advantage is architectural: publishers do not need to know which consumers exist, and subscribers do not need to know which device produced an event.
That separation is why MQTT works well for sensor telemetry, device state, commands, gateways, mobile clients, and services that connect over unreliable networks.
This overview focuses on the decisions that affect a real system rather than treating MQTT as a list of packet names.
What is the MQTT protocol?
MQTT is an application-layer messaging protocol that uses a broker to route messages from publishers to subscribers. Clients connect once, publish payloads to hierarchical topics, and subscribe to topic filters without depending on each other's address or availability. That decoupled model keeps device and service integrations small while the broker centralizes authentication, authorization, delivery state, and observability.
The four parts of an MQTT system
An MQTT deployment has four core concepts:
- Broker: accepts connections, authenticates clients, evaluates topic permissions, and routes messages.
- Client: any process or device that connects to the broker. A client may publish, subscribe, or do both.
- Topic: a hierarchical address such as
factory/site-a/line-2/motor-7/temperature. - Message: a payload plus delivery settings such as QoS, retain, expiry, and MQTT 5 properties.
Clients never send an MQTT publish directly to another client. The broker is always the routing boundary.
What happens during a connection
A client begins by opening a network connection to the broker. Production deployments normally use MQTT over TLS, commonly on port 8883. Browser clients usually use MQTT over secure WebSocket because browsers cannot open an arbitrary raw TCP socket.
The standard port is a useful starting point, but the transport and security policy matter more than the number:
| Port | Common transport | Appropriate use |
|---|---|---|
| 1883 | MQTT over TCP without TLS | Deliberately isolated local development only |
| 8883 | MQTT over TLS | Production devices and backend services |
| 443 | MQTT over secure WebSocket | Browsers and networks restricted to HTTPS traffic |
A production client should resolve the broker hostname, open the required TLS or WebSocket transport, validate the server certificate, and only then send MQTT CONNECT. Do not treat a reachable TCP port as a successful or trusted MQTT connection.
The client then sends a CONNECT packet containing settings such as:
- protocol version;
- client ID;
- clean-start or session behavior;
- keepalive interval;
- optional username and password;
- optional Last Will message;
- MQTT 5 properties.
The broker replies with CONNACK. A successful response confirms the connection, but it does not mean every topic is allowed. Authorization is evaluated when the client publishes or subscribes.
Client IDs must be unique among active connections. If two devices use the same client ID, the broker generally disconnects the earlier session. Generate IDs from a stable device identity instead of a copied sample string.
Publish-subscribe routing
A publisher sends a PUBLISH packet to one exact topic:
factory/shanghai/line-1/motor-7/telemetry
Subscribers register topic filters. A filter may be exact or use wildcards:
factory/shanghai/line-1/+/telemetry
factory/shanghai/#
The + wildcard matches one topic level. The # wildcard matches all remaining levels and must appear at the end. Broad filters are convenient for trusted backend consumers but are usually too permissive for field devices.
Topic names are visible routing metadata. Do not put passwords, personal data, or other secrets in them, even when transport is encrypted.
QoS is a delivery contract, not a quality score
MQTT defines three Quality of Service levels:
| QoS | Delivery behavior | Typical use |
|---|---|---|
| 0 | At most once | Frequent telemetry where a later sample replaces a lost one |
| 1 | At least once; duplicates are possible | State changes, alerts, and idempotent commands |
| 2 | Exactly once at the MQTT protocol layer | Rare workflows with a measured exactly-once requirement |
Higher QoS adds packet exchanges, broker state, client state, bandwidth, and latency. It does not guarantee that a downstream database or physical actuator processes a message exactly once.
For most connected products, QoS 0 and QoS 1 cover nearly every workload. Make QoS 1 consumers idempotent by including a message identifier or business operation ID.
Retained messages provide the latest value
When a publisher sets the retain flag, the broker stores the last retained message for that topic. A new subscriber receives it immediately after subscribing.
Retained messages work well for:
- current device state;
- last known configuration;
- online or offline status;
- a value that new subscribers need before the next live update.
They are not a general event-history system. A retained topic has one current retained value, not a queryable timeline. Send events to a database or streaming platform when consumers need history and replay.
Publish an empty retained payload to clear a retained value when the broker and client library follow the standard retained-message behavior.
Sessions define what survives a disconnect
An MQTT session can preserve subscriptions and queued QoS messages across a reconnect. This is useful for devices that move between networks or sleep to conserve power.
Session design must answer:
- Is the client ID stable?
- How long should the broker retain the session?
- Which QoS messages may queue while the device is offline?
- What queue limit prevents stale data from growing without bound?
- Should expired commands be discarded before reconnection?
MQTT 5 adds explicit session expiry and message expiry, making this lifecycle easier to express. Use them together. A persistent session without bounded expiry can become operational debt.
Last Will detects an ungraceful disconnect
A client may register a Last Will message during connection. If the broker detects that the client disappeared without a clean DISCONNECT, it publishes the Will on the client's behalf.
A common pattern is:
devices/device-042/status = offline
The client publishes online after connecting and registers offline as its retained Will. Consumers can then see a useful last-known availability state.
The Will is not an instant failure detector. Detection depends on the network and keepalive timing. Safety-critical systems still need device-local safeguards.
MQTT 5 features worth adopting
MQTT 5 adds capabilities that reduce application-specific conventions:
- Reason codes explain connection, publish, and subscription failures.
- Session expiry separates a clean connection start from how long session state survives.
- Message expiry prevents stale commands from being delivered later.
- Topic aliases reduce repeated topic-name overhead on long-lived connections.
- User properties carry small metadata fields without changing the payload.
- Response topic and correlation data support request-response flows.
- Shared subscriptions distribute matching messages across a subscriber group.
Adopt MQTT 5 when the broker and client fleet support it consistently. Do not silently depend on a feature that older clients negotiate away.
A production-ready protocol checklist
Before launch:
- require TLS and validate certificates;
- issue unique, revocable credentials per device;
- separate publish and subscribe permissions;
- document topic levels, payload schemas, units, and owners;
- choose QoS per message consequence;
- bound session and message expiry;
- test duplicate delivery and reconnect storms;
- monitor authentication failures, denied topics, queue depth, and connection churn.
The MQTT tutorial walks through a first publish-subscribe flow. The MQTT security guide goes deeper on transport, identity, and topic authorization. Use the public MQTT broker only for synthetic, disposable tests.
