Baud
All protocols

MQTT

Tiny publish/subscribe messages for sensors and small devices.

CONNECT

How a client says hello. Notice the length-prefixed strings and the packed flags byte.

MQTT CONNECT · 18 bytes081610·10·00·04·4DM51Q54T54T04·02·00·3C<00·04·64d65e6Dm6FoPac…Fla…Remaining…Protocol name lengthProtocol nameProtocol …Connect f…Keep aliveClient ID lengthClient IDClick a field to inspect it

Whole frame

10 10 00 04 4D 51 54 54 04 02 00 3C 00 04 64 65 6D 6F: the shortest useful CONNECT. Two header bytes plus a ten-byte variable header and a six-byte payload.

FieldOffsetExample valueMeaning
Packet typeByte 0, bits 7–41 = CONNECTThe top nibble says what this packet is: 1 CONNECT, 2 CONNACK, 3 PUBLISH, 4 PUBACK, 8 SUBSCRIBE, 9 SUBACK, 12 PINGREQ, 14 DISCONNECT.
FlagsByte 0, bits 3–00The low nibble is type-specific. CONNECT requires 0000.
Remaining lengthByte 116 bytes followBytes after this field: 16. It is a variable-length integer: 7 bits per byte, top bit = 'more bytes follow', so values up to 127 take one byte and a 256 MB packet takes four.
Protocol name lengthByte 2–34MQTT strings are a 2-byte length followed by UTF-8 bytes.
Protocol nameByte 4–7MQTTThe literal text 'MQTT'. A broker checks it to reject non-MQTT traffic early.
Protocol levelByte 84 = v3.1.14 = MQTT 3.1.1, 5 = MQTT 5.0.
Connect flagsByte 90x02 = Clean SessionWhich optional parts the payload contains and how the session behaves. Here only Clean Session is set.
Keep aliveByte 10–1160 sSeconds the client may stay silent. If the broker hears nothing for 1.5× this, it drops the connection. The client sends PINGREQ to stay within it.
Client ID lengthByte 12–134Length of the client identifier string.
Client IDByte 14–17demoA name the broker uses to identify this client. It must be unique: connecting twice with the same ID kicks the first one out.

Overview

MQTT is a lightweight publish/subscribe protocol on top of TCP. Devices connect to a broker; they publish messages to named topics and subscribe to topic patterns, and the broker routes between them. A packet has a 2-byte fixed header and often just a handful more bytes.

Three quality-of-service levels trade bandwidth for certainty: 0 fire and forget, 1 at least once, 2 exactly once.

Key facts

Transport
TCP 1883 (8883 with TLS)
Model
publish / subscribe via broker
Fixed header
2–5 bytes
QoS
0, 1, 2
Keep alive
PINGREQ / PINGRESP
Standard
OASIS MQTT 3.1.1 / 5.0

PUBLISH

A sensor reading to a topic: 15 bytes of overhead around a 4-byte payload.

MQTT PUBLISH (QoS 1) · 19 bytes081632211·00·09·68h6Fo6Dm65e2F/74t65e6Dm70p00·0ALF3223112E.355Pac…Fla…Remaining…Topic lengthTopicPacket identifierPayloadClick a field to inspect it

Whole frame

32 11 00 09 68 6F 6D 65 2F 74 65 6D 70 00 0A 32 31 2E 35: a four-byte reading sent to topic home/temp. The overhead is only 15 bytes, which is why MQTT suits tiny sensors on slow links.

FieldOffsetExample valueMeaning
Packet typeByte 0, bits 7–43 = PUBLISH3 = PUBLISH: carry a message to subscribers of a topic.
FlagsByte 0, bits 3–00010 = QoS 1For PUBLISH the flags carry delivery options. Here QoS = 1 ('at least once').
Remaining lengthByte 11717 bytes follow: 2 (topic length) + 9 (topic) + 2 (packet ID) + 4 (payload).
Topic lengthByte 2–39Length of the topic name.
TopicByte 4–12home/tempA hierarchical name with '/' separators. Subscribers can use wildcards such as home/+ or home/#. Messages are routed by topic, not by address.
Packet identifierByte 13–1410Present only when QoS > 0. The PUBACK echoes it so the sender knows which message was received.
PayloadByte 15–1821.5The message itself. MQTT does not care about its format: here it is the text '21.5'. It could be JSON or raw binary.

Publish with QoS 1

From subscribing to delivery and acknowledgement, with the broker in the middle.

SensorpublisherBrokertopic routerPhone appsubscriberSUBSCRIBEhome/# id=1SUBACKid=1, QoS 1PUBLISHhome/temp "21.5" id=10PUBLISHhome/temp "21.5"PUBACKid=...PUBACKid=10

Whole exchange

Publishers and subscribers never talk to each other: the broker routes by topic. The QoS level decides how many acknowledgements guard each message.

  1. 1The app subscribes

    The subscriber tells the broker which topics it wants. home/# is a wildcard for everything under home/.

  2. 2Broker confirms

    The broker confirms the subscription and the QoS it will use.

  3. 3The sensor publishes

    The sensor does not know who is listening. It just sends the reading to a topic, with QoS 1 and packet ID 10.

  4. 4Broker fans it out

    The broker forwards the message to every subscriber whose pattern matches the topic.

  5. 5App acknowledges

    The subscriber's PUBACK tells the broker the delivery is done. Without it the broker would retry.

  6. 6Sensor gets its receipt

    The broker acknowledges the sensor's packet ID 10: the message was accepted. If this never arrives, the sensor resends with DUP set. That is why QoS 1 means 'at least once'.

Where you meet it

  • IoT sensors and smart-home devices (Home Assistant, Zigbee2MQTT)
  • Telemetry from vehicles and industrial equipment on flaky links
  • Facebook Messenger used it for mobile push in its early days

Watch out for

  • Two clients with the same client ID kick each other off in a loop. Give each device a unique ID.
  • Retained messages stay on the broker until you publish an empty retained payload to the topic.
  • Topics are case-sensitive and a leading '/' creates a different, empty first level.

Standards

  • OASIS MQTT Version 3.1.1
  • OASIS MQTT Version 5.0

Related protocols