MQTT Fundamentals

What Is an MQTT Broker? A Beginner's Guide to Publish/Subscribe Messaging

An MQTT broker is the hub that routes every message between IoT devices and apps. Learn publish/subscribe, topics and wildcards, sessions, QoS, retained messages and last will, then try it hands-on in minutes.

Illustration of an MQTT broker routing messages between publishing sensors and subscribing applications
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

An MQTT broker is the central server that receives every MQTT message and delivers it to the clients that asked for it. In this beginner's guide you will learn how the publish/subscribe model works, what an MQTT broker does behind the scenes, how topics and wildcards are structured, how MQTT 3.1.1 and 5.0 differ, and how to send your first messages from the command line and Python.

What Is MQTT?

MQTT is a lightweight messaging protocol designed for devices with limited bandwidth, power or processing capacity. It runs over TCP (and over WebSocket for browsers), has a tiny fixed header of just two bytes, and keeps a single long-lived connection open instead of polling. That makes it a natural fit for sensors, gateways, vehicles, smart meters and industrial machines, and equally useful for dashboards and backend services that consume their data.

MQTT is an open OASIS standard; the official home of the protocol is mqtt.org.

The Publish/Subscribe Model

In a classic request/response system such as HTTP, a client calls a specific server and waits for the answer. MQTT uses publish/subscribe instead:

  • A publisher sends a message to a topic, for example home/livingroom/temperature.
  • A subscriber tells the broker which topics it is interested in.
  • The broker sits in the middle and forwards each message to every subscriber whose subscription matches the topic.

Here is the flow in words:

[Temperature sensor] --PUBLISH home/livingroom/temperature 22.5--> [MQTT broker]
[MQTT broker] --deliver--> [Mobile app]       (subscribed to home/+/temperature)
[MQTT broker] --deliver--> [Analytics service] (subscribed to home/#)

Three kinds of decoupling make this powerful:

  • Space: the sensor does not know the app's address, and the app does not know the sensor's. Both only know the broker.
  • Time: with persistent sessions and retained messages, a subscriber does not have to be online at the exact moment a message is published.
  • Scale: adding a tenth or a thousandth subscriber does not change the publisher at all.

What Does an MQTT Broker Do?

The MQTT broker is far more than a relay. It is responsible for several jobs at once.

Managing connections

Every client opens a TCP, TLS or WebSocket connection and sends a CONNECT packet with a client ID, optional username and password, a keep-alive interval and session flags. The broker authenticates the client, answers with CONNACK and then monitors the connection with PINGREQ/PINGRESP so it notices dead clients.

Keeping sessions

A session holds a client's subscriptions and any messages queued while it was offline. With a clean session the state is discarded on disconnect. With a persistent session the broker keeps it, so a device that drops off a mobile network receives what it missed when it returns. MQTT 5 replaces the old on/off flag with a session expiry interval measured in seconds.

Routing by topic

Each incoming PUBLISH is matched against all active subscriptions, including wildcard filters, and delivered to the matching clients. Routing is the heart of the MQTT broker, and it is why topic design matters.

Retained messages

A publisher can set the retain flag. The broker stores the last retained message per topic and immediately sends it to any new subscriber. This is ideal for state such as device/42/status = online or the latest configuration: a dashboard that opens later still sees the current value without waiting for the next update.

Last Will and Testament

When connecting, a client can register a "last will" message, for example device/42/status = offline. If the client disappears without a clean DISCONNECT (power loss, network failure, keep-alive timeout), the broker publishes the will on its behalf. Combined with a retained online message, this gives you reliable presence detection.

Quality of Service

MQTT defines three delivery guarantees, and the broker enforces them on both legs of the trip (publisher to broker, broker to subscriber):

QoS Name Guarantee Typical use
0 At most once Fire and forget, no acknowledgement Frequent sensor readings where a missed sample is fine
1 At least once Acknowledged with PUBACK, may be duplicated Most telemetry and events
2 Exactly once Four-step handshake, no duplicates Billing, commands that must not repeat

The effective QoS for a subscriber is the lower of the publish QoS and the subscription QoS. For a deeper dive, read MQTT QoS Levels Explained.

MQTT Topics and Wildcards

Topics are UTF-8 strings split into levels by a forward slash. They are created on the fly: there is nothing to declare in advance.

factory1/line1/cnc1/temperature
factory1/line1/cnc1/spindle_rpm
factory1/line2/press3/status
home/kitchen/light/state

Good topic design reads from general to specific, avoids leading slashes and spaces, and does not put sensitive data in topic names. Topics starting with $ are reserved for the broker, for example ConnectMQ publishes $SYS/broker/connection/{clientId}/state.

Single-level wildcard: +

The plus sign matches exactly one level.

Subscription filter Matches Does not match
factory1/+/cnc1/temperature factory1/line1/cnc1/temperature factory1/line1/cell2/cnc1/temperature
home/+/light/state home/kitchen/light/state home/light/state

Multi-level wildcard:

The hash matches any number of levels, including zero, and must be the last character of the filter.

Subscription filter Matches
factory1/# factory1, factory1/line1/cnc1/temperature, factory1/line2/press3/status
factory1/line1/# Everything below factory1/line1
# Every non-$ topic the client is allowed to see

Wildcards can only be used when subscribing; you always publish to a concrete topic. In industrial projects, a consistent hierarchy such as ISA-95 (enterprise, site, area, line, cell) becomes a Unified Namespace; see MQTT Sparkplug B and Unified Namespace for that pattern.

MQTT 3.1.1 vs MQTT 5.0

Most brokers and libraries today support both versions. MQTT 5.0 keeps the same model and adds features that make large deployments easier to run.

Capability MQTT 3.1.1 MQTT 5.0
Error feedback Limited return codes Reason codes on most acknowledgements (for example 0x97 Quota exceeded)
Session lifetime Clean session on/off Session expiry interval
Message lifetime Not available Message expiry interval
Load balancing Not in the standard Shared subscriptions $share/{group}/{filter}
Bandwidth savings Full topic every time Topic aliases
Request/response Ad hoc conventions Response topic and correlation data
Broker limits Implicit Announced in CONNACK (Maximum QoS, Receive Maximum, etc.)
Metadata Payload only User properties

If you are starting a new project, use MQTT 5.0 unless a device library only supports 3.1.1. The full specification is published by OASIS at docs.oasis-open.org, and our overview of MQTT 5 features covers the practical highlights.

Hands-On: Try an MQTT Broker in Five Minutes

The quickest way to understand an MQTT broker is to use one. broker.connectmq.com offers a public area for anonymous testing.

Protocol Port URL
MQTT (TCP) 1883 mqtt://broker.connectmq.com:1883
MQTT over TLS 8883 mqtts://broker.connectmq.com:8883
WebSocket 8083 ws://broker.connectmq.com:8083/mqtt
Secure WebSocket 8084 wss://broker.connectmq.com:8084/mqtt

Rules for the public area: connect without a username or password, use a unique, non-empty client ID (an empty one is rejected), and remember that anything you publish is readable by anyone. Pick a random prefix such as connectmq/demo/<your-random-id>/ and never send personal or sensitive data. Limits are 64 KB per message, 10 messages per second and 10 subscriptions per client, and up to 8 topic levels.

Subscribe and publish with mosquitto

Install the Eclipse Mosquitto command-line clients, then open a terminal and subscribe with a wildcard. Replace k9x2 with your own random string:

mosquitto_sub -h broker.connectmq.com -p 1883 -i sub-k9x2 \
  -t "connectmq/demo/k9x2/#" -v

In a second terminal, publish a reading:

mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-k9x2 \
  -t "connectmq/demo/k9x2/room1/temp" -m '{"temp":22.5}' -q 1

The first terminal prints:

connectmq/demo/k9x2/room1/temp {"temp":22.5}

Now try a retained message. Publish a status with -r, then start a fresh subscriber that only uses the single-level wildcard:

mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-k9x2 \
  -t "connectmq/demo/k9x2/room1/status" -m "online" -r

mosquitto_sub -h broker.connectmq.com -p 1883 -i sub2-k9x2 \
  -t "connectmq/demo/k9x2/+/status" -v -C 1

The new subscriber receives online immediately, even though it connected after the message was sent. That is the broker storing and replaying the retained value. To clear it, publish an empty retained message with -r -n.

For encrypted traffic, switch to port 8883 and point the client at your system's CA certificates (for example --capath /etc/ssl/certs on Linux), and add -V mqttv5 to speak MQTT 5.0.

Python example with a last will

Install paho-mqtt 2.x with pip install paho-mqtt and run:

import json
import uuid
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PREFIX = f"connectmq/demo/{uuid.uuid4().hex[:8]}"
CLIENT_ID = f"py-{uuid.uuid4().hex[:8]}"


def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe(f"{PREFIX}/#", qos=1)
    client.publish(f"{PREFIX}/sensor1/status", "online", qos=1, retain=True)
    client.publish(f"{PREFIX}/sensor1/temp", json.dumps({"temp": 21.8}), qos=1)


def on_message(client, userdata, msg):
    print(f"{msg.topic} -> {msg.payload.decode()}")


client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id=CLIENT_ID,
    protocol=mqtt.MQTTv5,
)
client.will_set(f"{PREFIX}/sensor1/status", "offline", qos=1, retain=True)
client.on_connect = on_connect
client.on_message = on_message

client.connect(BROKER, 1883, keepalive=30)
client.loop_forever()

The script registers a last will, announces itself as online with a retained message and publishes a temperature reading that it receives back through its own wildcard subscription. If you kill the process abruptly, the broker publishes offline on the status topic once the keep-alive expires.

Want to use the browser instead? The same broker accepts WebSocket connections on 8083 and 8084; see MQTT over WebSocket.

From Public Test Broker to Production

A public MQTT broker is perfect for learning and prototypes, but production needs private credentials, TLS and isolation from other users. ConnectMQ runs the broker for you: create one in the portal, receive a username, password and client ID, and connect over mqtts:// on port 8883. Your topics stay isolated from other tenants and from the public area, and the portal gives you a live topic explorer, dashboards and alert rules. Read What Is a Managed MQTT Broker? to compare hosting options.

Get Started with ConnectMQ

Sign up at app.connectmq.com to create your own MQTT broker on the free Serverless plan, no credit card required. You will be sending messages over TLS in a few minutes, with the same commands you just tried.

Frequently Asked Questions

What is an MQTT broker in simple terms?

An MQTT broker is a server that receives messages from publishing clients and forwards them to every client subscribed to a matching topic. Devices never talk to each other directly; they only talk to the broker.

What is the difference between an MQTT broker and an MQTT client?

A client is any device or application that publishes or subscribes, such as a sensor or a dashboard. The broker is the server in the middle that authenticates clients, keeps sessions and routes messages between them.

Which port does an MQTT broker use?

The standard ports are 1883 for plain MQTT and 8883 for MQTT over TLS. WebSocket connections commonly use separate ports; on broker.connectmq.com they are 8083 and 8084 with the path /mqtt.

Is there a free MQTT broker I can test with?

Yes. broker.connectmq.com has an anonymous public area for testing, and ConnectMQ's free Serverless plan gives you a private broker with credentials and TLS.

Should I use MQTT 3.1.1 or MQTT 5.0?

Use MQTT 5.0 for new projects because it adds reason codes, session and message expiry, shared subscriptions and topic aliases. Fall back to 3.1.1 only when a device library does not support version 5.

Related articles

Why Your MQTT Client Keeps Disconnecting (and How to Fix It)

Reconnect loops are one of the most common MQTT problems. Learn the five usual causes, from duplicate client IDs to keep alive timeouts and oversized packets, and follow a diagnosis flow that pinpoints yours.

8 min read

Who Invented MQTT? The History from Oil Pipelines to IoT

MQTT was invented in 1999 by Andy Stanford-Clark of IBM and Arlen Nipper of Arcom to monitor oil pipelines over satellite. Follow its path to open source, OASIS, ISO and today's managed cloud brokers.

7 min read

MQTT Maximum Message Size: Limits and Large Payload Strategies

MQTT can technically carry a 256 MB packet, but brokers, client libraries and devices impose far lower limits. Learn where the real limits are, what happens when you exceed them, and how to send large payloads.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.