Topic Name
The publisher's exact route, such as factory/line_a/machine_012/temperature. Publish topics do not use wildcards.
Before the broker can route anything, a team has to name the message. building/2/room/214/temperature tells a clearer story than sensor1: it reveals place, device role, and the kind of reading a subscriber expects. Good MQTT topic design starts with the subscriber’s question, then works backward to names, filters, wildcards, and access boundaries.
An MQTT topic is a case-sensitive UTF-8 name attached to a published message. Brokers do not inspect the payload to decide who receives the message; they compare the published topic with each subscriber's topic filter.
+ fills exactly one missing level, # takes the rest of a subtree, and publishers still send concrete topic names without wildcards.Read the diagram from the concrete topic tree downward. The publisher sends names such as home/kitchen/temp; the subscriber chooses how much of that tree it wants. home/+/temp is selective because it fixes the first and last levels while allowing one room name to vary. home/kitchen/# is broader because it accepts anything below the kitchen branch, including deeper subtopics. Those two wildcard types solve different routing problems, so a good topic plan keeps levels consistent enough that a subscriber can choose the narrowest filter that still covers its job. If a team cannot explain which level each wildcard represents, the topic tree is not yet stable enough for production ACLs or dashboards. Review filters with real sample topics before release.
Broker Bex
“A message with no subscriber is a tree falling in an empty forest — design the topic before the payload.”
Through this chapter, Bex reads the topic tree the same way every time: name first, filter second, subscriber last.
The publisher's exact route, such as factory/line_a/machine_012/temperature. Publish topics do not use wildcards.
The subscriber's match pattern. It may be exact or use the MQTT wildcards + and #.
Each segment between slashes is a level. The levels in home/kitchen/thermostat/state are home, kitchen, thermostat, and state.
Rule of thumb: design topics around stable routing questions: who owns the device, where it is, which asset it represents, and what measurement or command it carries.
factory/line_a/machine_012/temperature
factory/line_a/machine_012/vibration
factory/line_b/machine_004/pressure
/Factory/Line A/Machine 012 Temperature
machine_012_temperature
factory/line_a/machine_012/status_and_command
The best topic tree is not simply a directory of devices. It is a set of routes that lets dashboards, alarms, automation services, and maintenance tools subscribe without client-side filtering.
Identify dashboards, analytics jobs, control services, and alerting systems before naming the levels.
Use durable groups such as factory, line_a, building_b, or fleet.
Ending with temperature, pressure, command, or state keeps wildcard filters useful.
factory/line_a/#factory/+/+/pressurefactory/line_a/machine_012/+#Common mistakes: leading slashes create an empty first level; spaces and mixed case produce inconsistent client code; flat topics such as sensor_001_temp prevent useful wildcard subscriptions; one topic should not carry both desired commands and reported state.
Bex’s Topic Board
factory, line_a, building_b, fleet — then end with the metric or role.factory/line_a/# receives every topic below one production line, the shape a maintenance screen owns.Design review should therefore start with example subscriptions, not just example publishes. If a dashboard needs all pressure readings on one line, the hierarchy must put line and measurement in stable positions. If a controller must write commands to one device but only read state from the same device, the command and state branches should be separate levels so ACLs can express that difference. Treat every wildcard as a contract with future subscribers: it should be obvious which levels are allowed to vary and which levels are intentionally fixed. Keep a short table of approved filters beside the topic naming standard.
Every subscription adds broker state. Exact filters are easiest to reason about, but a large fleet that subscribes one topic at a time can create a large reconnect burst. A small number of well-shaped wildcard filters reduces subscription count while still keeping unwanted messages out of the client.
+ Matches One Levelhome/+/temperature matches home/kitchen/temperature but not home/kitchen/sensor_7/temperature.
# Matches A Subtreehome/kitchen/# matches home/kitchen, home/kitchen/temperature, and deeper topics. It must be the final level in the filter.
A device can be allowed to publish devices/device_042/state/# while a controller can publish devices/device_042/command/#.
Reserved namespaces: broker system topics commonly live under prefixes such as $SYS/. Do not rely on a broad application filter to cover broker-reserved namespaces; subscribe to those namespaces explicitly when you need them.
Bex’s Topic Board
home/+/temperature matches home/kitchen/temperature, not a deeper home/kitchen/sensor_7/temperature.# must be the final level in the filter — it takes a topic and everything deeper beneath it.state/# while a controller owns command/#.Under load, the broker's topic matcher benefits from a hierarchy that avoids both extremes. Thousands of exact subscriptions can make reconnect storms expensive because each client must reinstall a long list of filters. A catch-all # filter is cheap to install but expensive and risky to use because it sends unrelated traffic to the client and moves authorization mistakes into application code. The balanced design is a small set of precise wildcard filters whose level positions mirror product boundaries: site, line, asset, direction, and measurement or command. That same shape also makes retained-message cleanup and audit logs easier, because topic prefixes map to real ownership boundaries instead of arbitrary strings.
A client that installs 50 exact filters on every reconnect causes more broker work than a client that installs 3-5 precise wildcard filters.
Replacing all filters with # reduces subscription count but pushes unwanted traffic and security decisions into application code.
MQTT topic design is the routing plan for a publish-subscribe system. Publishers send to exact topic names, subscribers install exact or wildcard topic filters, and the broker matches those filters without interpreting the payload.
Use stable, hierarchical names such as factory/line_a/machine_012/temperature. Use + when one level varies and # when a whole subtree is intentionally in scope. Avoid leading slashes, spaces, mixed naming styles, flat topic strings, and topic paths that mix commands with reported state.
Design MQTT topics from subscriber needs backward. A good hierarchy lets dashboards, safety services, maintenance tools, and ACL policies use a small number of precise filters instead of broad catch-all subscriptions or long lists of exact topics.