3  MQTT Topic Design and Wildcards

mqtt
topics
wildcards

3.1 Start With The Topic Name

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.

3.2 MQTT Topics Are Message Addresses; Filters Choose Which Addresses A Client Receives

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.

MQTT topic wildcard diagram showing a home topic hierarchy, plus wildcard examples for single-level matches, hash wildcard examples for multi-level subtree matches, and rules for wildcard placement.
Topic filters are routing rules: + 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, the messaging guide

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.

Topic Name

The publisher's exact route, such as factory/line_a/machine_012/temperature. Publish topics do not use wildcards.

Topic Filter

The subscriber's match pattern. It may be exact or use the MQTT wildcards + and #.

Topic Level

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.

Good Shape

factory/line_a/machine_012/temperature
factory/line_a/machine_012/vibration
factory/line_b/machine_004/pressure

Fragile Shape

/Factory/Line A/Machine 012 Temperature
machine_012_temperature
factory/line_a/machine_012/status_and_command

3.3 Design The Hierarchy From Consumers Back To Publishers

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.

1. List Consumers

Identify dashboards, analytics jobs, control services, and alerting systems before naming the levels.

2. Put Stable Groups First

Use durable groups such as factory, line_a, building_b, or fleet.

3. End With The Metric Or Role

Ending with temperature, pressure, command, or state keeps wildcard filters useful.

Filter
Receives
Use When
factory/line_a/#
Every topic below one production line
A maintenance screen owns the whole line view.
factory/+/+/pressure
Pressure readings where exactly two middle levels vary
A safety service only needs pressure topics across lines and machines.
factory/line_a/machine_012/+
One metric level for one machine
A local diagnostic tool wants all current readings for a specific asset.
#
Nearly everything except broker-reserved namespaces on many brokers
Temporary debugging only; do not make broad catch-all filters the product design.

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

  • Topic: put stable groups first — factory, line_a, building_b, fleet — then end with the metric or role.
  • Filter: factory/line_a/# receives every topic below one production line, the shape a maintenance screen owns.
  • Subscriber: one topic should not carry both desired commands and reported state — keep those as separate levels so ACLs can tell them apart.

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.

3.4 Topic Filters Trade Precision For Subscription Scale

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 Level

home/+/temperature matches home/kitchen/temperature but not home/kitchen/sensor_7/temperature.

# Matches A Subtree

home/kitchen/# matches home/kitchen, home/kitchen/temperature, and deeper topics. It must be the final level in the filter.

ACLs Follow The Same Shape

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

  • Topic: home/+/temperature matches home/kitchen/temperature, not a deeper home/kitchen/sensor_7/temperature.
  • Filter: # must be the final level in the filter — it takes a topic and everything deeper beneath it.
  • Subscriber: ACLs follow the same shape as topics — a device publishes its own 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.

Reconnect Cost

A client that installs 50 exact filters on every reconnect causes more broker work than a client that installs 3-5 precise wildcard filters.

Overbroad Filters

Replacing all filters with # reduces subscription count but pushes unwanted traffic and security decisions into application code.

3.5 Summary

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.

3.6 Key Takeaway

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.

3.7 See Also