MQTT Topic Naming Best Practices for IoT Projects
MQTT topic names become an API between firmware, dashboards, automations and data storage. A topic scheme that feels fine with one ESP32 can become confusing when you add more rooms, devices, sensor types and commands.
A good scheme is predictable, easy to subscribe to, straightforward to authorize and stable enough that a firmware update does not silently break consumers. This guide gives a reusable starting convention rather than a universal standard; adapt names to your project and document the contract.
1. Design a hierarchy around stable identity
One practical convention is site/area/device/message-type/field. For example:
- solderhub/lab/esp32-01/telemetry
- solderhub/lab/esp32-01/state/led
- solderhub/lab/esp32-01/command/led
- solderhub/lab/esp32-01/status
Not every project needs five levels. Choose a hierarchy that makes common subscriptions easy. Use stable device identifiers rather than a human label likely to change, and document payload fields. Do not encode every value in the topic when a JSON payload is better suited to changing measurement sets.
2. Separate telemetry, command, reported state and availability
Telemetry describes measurements. A command expresses requested behavior. Reported state describes what the device says it actually did. Availability indicates whether the broker believes a client is connected.
This separation prevents dashboards from confusing a request with a confirmed result. It also makes permissions easier to reason about: a sensor can publish measurements but should not automatically receive every actuator command. For physical outputs, define boot and offline policies separately; a broker message is not a safety interlock.
3. Use + and # correctly
MQTT supports two wildcards in subscription filters:
- + matches one topic level.
- # matches the remaining hierarchy and is used at the end of the filter.
Examples: solderhub/lab/+/telemetry matches telemetry for one level of device IDs; solderhub/lab/# matches descendants under the lab prefix. A broad wildcard can pull in many messages. Use it when the consumer really needs them, not as a shortcut for a well-scoped subscription. Topic names are case-sensitive, so Temperature and temperature differ.
4. Naming mistakes to avoid
Avoid spaces, inconsistent casing, changing names without a migration plan, using a topic as an authentication secret, and placing sensitive personal data in topic names. Keep a documented distinction between state and command topics. Do not use wildcard symbols in ordinary published topic names; wildcards belong in subscription filters.
Do not change a topic hierarchy simply because a display label changes. For a measurement such as pressure or temperature, a stable telemetry topic plus a structured payload can be more durable than embedding every field in a long topic path.
5. Retain only messages that represent current state
Retained messages help a new subscriber learn the latest retained value for a topic. They are appropriate for current reported state or availability in many designs. They are not a complete history; each new retained publication replaces the previous value for that topic.
Avoid retained one-shot commands such as TOGGLE, UNLOCK or PULSE unless replay is explicitly intended and safe. For many actuator designs, use non-retained commands and retain the reported state instead. If desired-state retention is required, implement it as an explicit policy and publish what the device actually applied.
6. Align topic names with permissions
A good hierarchy makes ACL rules more readable. A temperature sensor might be allowed to write only to its own telemetry and status topics. A dashboard may read telemetry but publish commands only to specific command topics. Give each identity the minimum permissions required.
Topic design does not itself enforce these rules; configure broker authentication and authorization. Check your broker version's documentation before applying example ACL syntax. Use TLS or a suitable private network when credentials and control messages cross untrusted links.
Topic design checklist
- Prefix topics with a project/site namespace where useful.
- Use stable device IDs.
- Separate telemetry, command, state and status.
- Document payload fields and measurement units.
- Use wildcards only when broad subscriptions are intended.
- Keep casing consistent and avoid spaces.
- Retain current state selectively; do not retain one-shot actions casually.
- Match broker ACLs to the topic hierarchy.
- Version or migrate the topic contract when breaking changes are unavoidable.
A written topic contract helps the next person who builds a firmware update, Node-RED flow or dashboard against your broker.