Protocols and data

What is MQTT? The MQTT protocol explained

MQTT is a publish and subscribe protocol: clients send messages to topics on a broker, which passes them on to subscribers. Topics, QoS, ports, MQTT 5.

MQTT is a lightweight publish and subscribe messaging protocol. Devices and applications connect to one server, the broker, and send messages to named topics such as site/dub01/mdb1/main-incomer. Any client that has subscribed to that topic receives the message from the broker. Publishers and subscribers never address each other, so a meter, a dashboard and a cloud platform can share data without knowing about each other. MQTT runs over TCP on port 1883, or over TLS on port 8883, and its fixed header is only two bytes. Because every device connects outwards to the broker and any number of systems can subscribe to the same data, it has become the most common protocol for sending sensor and meter telemetry over the internet.

How MQTT works

PartWhat it doesExample
BrokerAccepts connections, checks permissions and forwards each message to matching subscribersEclipse Mosquitto on a server, or a cloud IoT service
ClientAny device or application that connects to the broker, to publish, subscribe or bothA Gateway, a dashboard, a database writer
TopicA text address with levels separated by /site/dub01/mdb1/main-incomer
MessageA topic, a payload of up to 256 MB and a few flagsA JSON object with the readings
SubscriptionA topic filter, with optional wildcardssite/dub01/#
QoSThe acknowledgement level on each hop0, 1 or 2
SessionThe broker's memory of a client's subscriptions and undelivered messagesKept across a reconnect if the client asks for it

A client opens a TCP connection to the broker and sends CONNECT with its client identifier, credentials and a keep-alive interval. The broker answers CONNACK. A publisher then sends PUBLISH packets; a subscriber sends SUBSCRIBE with one or more topic filters, and the broker sends it every matching PUBLISH from then on. If no packet passes within the keep-alive interval, the client sends PINGREQ, and the broker closes a connection that stays silent for one and a half times the interval.

Because every client makes an outgoing connection to the broker, a site Gateway needs no open inbound port. This is the main practical reason MQTT replaced polled protocols for sending data off site.

Topics and wildcards

Topics are case-sensitive strings. A client does not create a topic; it publishes to it, and the broker routes the message to every subscription that matches. A subscription can use two wildcards:

FilterMatchesDoes not match
site/dub01/mdb1/+site/dub01/mdb1/main-incomer, site/dub01/mdb1/chiller-2site/dub01/mdb1/chiller-2/alarm
site/dub01/#Every topic under site/dub01, at any depthsite/cork02/mdb1/main-incomer
site/+/mdb1/main-incomerThat meter on every siteOther meters

+ matches one level and # matches the rest of the tree, so it must come last. Topics that start with $ are reserved for the broker, such as $SYS/ for broker statistics, and a filter that starts with a wildcard does not match them.

Plan the topic tree before the first device publishes, because every subscriber and access rule depends on it. A good tree runs from the widest scope to the narrowest (organisation, site, panel, device, then the type of message), keeps one device in one place, and leaves out values that change, such as a reading, a timestamp or a session number. Separate telemetry, status and command topics, so that write permission can be given only where it is needed.

QoS, retained messages and last will

MQTT has three delivery levels. They apply to one hop at a time: publisher to broker, and broker to each subscriber.

QoSDeliveryPackets on one hopTypical use
0At most oncePUBLISHFrequent readings where a lost one is soon replaced
1At least once, duplicates possiblePUBLISH, PUBACKMeter readings and events that must arrive
2Exactly once on that hopPUBLISH, PUBREC, PUBREL, PUBCOMPRare; costs four packets per message

A retained message is kept by the broker as the last value of its topic and sent to every new subscriber at once, which suits a device status but can deliver a stale reading. A last will is a message the broker publishes for a client when its connection drops without a clean DISCONNECT, which is how a subscriber learns that a Gateway has gone offline. The MQTT QoS and retained messages guide covers both in detail, with message expiry and persistent sessions.

MQTT ports and security

PortTransportUse
1883TCPMQTT without encryption: only on a closed local network
8883TLS over TCPMQTTS: the normal choice over the internet or a shared network
443 (or another)WebSocket over TLSBrowsers, and networks that allow only HTTPS

MQTT itself has a username and password field and nothing else. Encryption, server identity and client certificates come from TLS, and access control comes from the broker's rules on which client may publish or subscribe to which topics. The MQTTS guide explains certificates, server name checks and how to test a TLS connection from the command line.

MQTT 3.1.1 vs MQTT 5

MQTT was designed in 1999 for pipeline telemetry over satellite links. OASIS published MQTT 3.1.1 as a standard in 2014, which became ISO/IEC 20922 in 2016, and MQTT 5.0 in 2019. Most brokers support both, and many devices still speak only 3.1.1.

MQTT 3.1.1MQTT 5.0
AcknowledgementsSuccess or a few CONNACK codesA reason code on every acknowledgement, including refusals
SessionClean session on or offSession expiry interval
Message lifetimeNoneMessage expiry interval
MetadataNoneUser properties, content type, payload format indicator
Load sharingBroker-specificShared subscriptions ($share/group/topic)
BandwidthFull topic every timeTopic aliases replace a long topic with a number
Request and responseBy conventionResponse topic and correlation data
Flow controlNoneReceive maximum and maximum packet size

For telemetry, the most useful MQTT 5 features are reason codes, because a client can see that the broker refused a message, and message expiry, because a command delayed by an outage is discarded instead of executed late.

Payloads: JSON, Sparkplug B and the data contract

MQTT carries bytes and says nothing about what they mean. Most energy platforms expect JSON, for example:

JSON
{"ts":"2026-10-28T09:15:00Z","kW":184.2,"kWh":1532871.4,"V1":231.4,"PF":0.94,"q":"good"}

The topic says which meter it is; the payload carries the measurement time, the values and a quality flag. The units and the meaning of each key have to be written down and agreed with every subscriber: kW or W, import or net energy, the meter's time or the time the Gateway received it. That agreement, not MQTT support, is what makes two systems work together. The interoperability guide lists what a data contract should fix, and the source time and arrival time guide explains why the measurement time belongs in the payload.

Sparkplug B, an Eclipse Foundation specification common in industrial systems, fixes the contract instead. Topics follow spBv1.0/<group>/<message type>/<edge node>/<device>, payloads are binary Protocol Buffers, and every edge node publishes a birth certificate listing its metrics and a death certificate (sent through the last will) when it disconnects. A subscriber can then discover devices and mark data as stale without any custom agreement, at the cost of a binary format that needs a Sparkplug-aware client to read.

Worked example: how much data does MQTT telemetry use?

Fifty meters each publish the JSON message above every 10 seconds at QoS 1. The payload is 88 bytes and the topic 28 bytes, so each PUBLISH packet is about 122 bytes. TLS adds about 22 bytes per record and TCP and IP about 52 bytes per segment, so each message is roughly 200 bytes on the wire.

One message per meterOne message per site
Messages per day50 × 8,640 = 432,0008,640
Size of each message on the wireabout 200 bytesabout 3,900 bytes (50 readings)
Data sent per dayabout 86 MBabout 34 MB
Data per monthabout 2.6 GBabout 1 GB

The per-site message carries the 50 readings as one JSON array of about 3,650 bytes (about 73 bytes per meter, with one timestamp for the whole message) plus the topic and headers, which TCP splits into three segments.

The PUBACKs coming back add a further 30 MB or so a day in the first case. On a fixed line none of this matters; on a cellular SIM it decides the data plan. Batching the readings of one site into one message, or sending changes only, cuts the overhead. The interval demand calculator helps to choose an interval that still answers the question the data is for.

MQTT compared with other protocols

MQTTHTTP (REST)Modbus TCPOPC UA
PatternPublish and subscribe through a brokerRequest and responseRequest and response, client pollsClient and server, with subscriptions; also a publish and subscribe mode
Who connectsEvery client connects out to the brokerClient to serverClient to each deviceClient to each server
Data modelNone: the payload is freeNone: defined by the APINumbered registersTyped nodes with units and status
Typical placeSite to cloud, device to platformOccasional uploads, web APIsMeters and controllers on sitePlant systems and SCADA

MQTT is usually the link from a site to a platform, while Modbus, BACnet and OPC UA read the devices on the site. The OPC UA vs Modbus vs MQTT guide compares them for industrial projects, and what is Modbus explains the polled side.

MQTT with EpiSensor

Edge on the ZGW-20 Gateway reads Zigbee, Modbus, BACnet and LoRaWAN devices on site, records each reading with its measurement time, and publishes to a platform's broker as an MQTT client, normally over MQTTS on port 8883 with a client certificate. It publishes at QoS 1 and keeps failed deliveries in a local queue, replaying them with their original timestamps when the broker returns. The topics and payload follow the platform's contract, and Connect Edge to your platform shows the ways Edge sends data out.

Common questions

What is MQTT used for?

MQTT carries small, frequent messages between devices and applications: sensor and meter readings, status changes and commands. It is used in building and energy monitoring, industrial telemetry, vehicle tracking and home automation, because one connection per device is enough and the protocol overhead is a few bytes per message.

What is an MQTT broker?

The broker is the server at the centre of MQTT. Clients connect to it, publish messages to topics and subscribe to topics. The broker checks each client's permissions, keeps sessions and retained messages, and forwards each message to every client with a matching subscription. Eclipse Mosquitto, EMQX and HiveMQ are common brokers, and the large cloud IoT services include one.

What port does MQTT use?

TCP port 1883 for MQTT without encryption and TCP port 8883 for MQTT over TLS (MQTTS). Both are registered with IANA. MQTT over WebSockets has no fixed port; it often runs on 443 behind a web server, which helps where a firewall allows only HTTPS.

Is MQTT TCP or UDP?

MQTT runs over TCP, or over another transport that delivers bytes in order without loss, such as TLS or WebSockets. A separate protocol, MQTT-SN, is designed for sensor networks and can run over UDP.

What is the difference between MQTT and HTTP?

HTTP is request and response: a client asks a server and waits for an answer, and a new request is needed for each piece of data. MQTT keeps one connection open and the broker pushes each message to subscribers as it arrives. For frequent small readings MQTT uses less bandwidth and delivers changes sooner; HTTP is simpler for occasional uploads and for systems that only expose a REST API.

What is the difference between MQTT 3.1.1 and MQTT 5?

MQTT 5 keeps the same model and adds reason codes on every acknowledgement, message and session expiry, user properties, shared subscriptions, topic aliases and request and response topics. A broker that supports MQTT 5 still accepts MQTT 3.1.1 clients, so both often run side by side.

What is Sparkplug B?

Sparkplug is an Eclipse Foundation specification that adds a fixed topic namespace, a binary payload and birth and death messages on top of MQTT. A subscriber can then discover the metrics of each edge node and know when its data is stale. MQTT itself defines none of these.