A good smart home MQTT topic structure is the difference between automations you can read at a glance and a tangle of sensor1/temp2 topics nobody remembers. In this guide you will get a ready-to-use room/device/property layout, learn why command and state topics must be separate, and see how retained messages, availability and wildcards fit together on a real broker.
Why Topic Design Matters Before the Tenth Device
With three devices, any naming works. By the time you have thirty, topic names decide how easy it is to:
- subscribe to "everything in the kitchen" or "every temperature in the house" with one wildcard,
- add a new device without editing every automation,
- tell whether a message is a request or a fact,
- see in a topic explorer what is actually happening.
MQTT does not enforce any structure. Topics are just UTF-8 strings split by /, and the broker matches subscriptions against them. That freedom is exactly why you need a convention. If the basics of how the broker routes these messages are new to you, start with what an MQTT broker does.
The Recommended Layout: Home, Room, Device, Property
A layout that scales well for most homes is:
<home>/<room>/<device>/<property>[/set]
Examples:
home1/kitchen/ceiling-light/power state: "ON" or "OFF" (retained)
home1/kitchen/ceiling-light/power/set command: "ON", "OFF", "TOGGLE"
home1/kitchen/ceiling-light/brightness state: 0-100 (retained)
home1/kitchen/ceiling-light/brightness/set command: 0-100
home1/livingroom/climate/temperature state: 21.6 (retained)
home1/livingroom/climate/humidity state: 48 (retained)
home1/garage/door/state state: "open", "closed", "opening" (retained)
home1/garage/door/state/set command: "OPEN", "CLOSE"
home1/garage/door/availability "online" or "offline" (retained, last will)
Why this order works:
| Level | Purpose | Wildcard example |
|---|---|---|
home |
Separates sites (house, holiday flat, parents' home) | home1/# |
room |
Matches how people think and speak | home1/kitchen/# |
device |
One physical or logical device | home1/+/climate/# |
property |
One value or capability | home1/+/+/temperature |
set suffix |
Marks a command, not a fact | home1/+/+/+/set |
Keep the depth at five levels or fewer. Deep trees are harder to type and the public test broker limits topics to eight levels anyway, which is a sensible ceiling for a home.
Command vs State Topics in a Smart Home MQTT Topic Structure
The single most important rule: never use the same topic for commands and state.
If a light listens and reports on home1/kitchen/ceiling-light/power, then a dashboard that publishes ON will see its own message echoed back, cannot tell whether the light actually switched, and a retained ON command will turn the light back on every time the device reconnects, even after someone switched it off at the wall.
With separate topics the flow is unambiguous:
- The dashboard publishes
ONto.../power/set(not retained). - The device switches the relay.
- The device publishes
ONto.../powerwith the retain flag. - Every subscriber, including the dashboard, updates from the state topic.
The state topic becomes the single source of truth. Commands are requests that may fail; states are facts the device confirms.
Retain state, never retain commands
Retained messages let a newly connected client see current state immediately. That is exactly what you want for states and availability, and exactly what you do not want for commands. A retained OPEN on a garage door command topic is a door that opens itself after every power cut. Our MQTT garage door opener tutorial shows this pattern in a project where getting it wrong has real consequences.
Choose QoS per topic type
States from sensors are fine at QoS 0 or 1; a missed temperature is replaced by the next one. Commands should use QoS 1 so they are delivered at least once, and devices should treat repeated commands as idempotent (ON twice is still on). For the trade-offs, see MQTT QoS levels explained.
Availability and Last Will
Every device should publish an availability topic. Set it to online (retained) after connecting and configure a last will message of offline (retained) on the same topic. If the device loses power or Wi-Fi, the broker publishes the will for it, and dashboards can grey out the device instead of showing a stale value as current.
// ESP32 with PubSubClient: last will on connect, then announce online
const char* AVAIL = "home1/garage/door/availability";
if (mqtt.connect(clientId, user, pass, AVAIL, 1, true, "offline")) {
mqtt.publish(AVAIL, "online", true);
mqtt.subscribe("home1/garage/door/state/set", 1);
}
Payload Conventions
Topic structure and payload format go together. Pick one approach and use it everywhere:
- One value per topic (
.../temperature=21.6) is simple, works with every tool, and makes wildcards powerful. - JSON per device (
.../climate={"temperature":21.6,"humidity":48}) reduces message count and keeps related values consistent.
Many homes use both: JSON for multi-sensor devices from Zigbee2MQTT or ESPHome, single values for DIY devices. If you do use JSON, document the keys and include units either in the key name (temp_c) or a schema note. Avoid mixing 21.6, "21.6" and "21.6 C" across devices.
Naming Rules That Prevent Pain
- Use lowercase, hyphen-separated names:
ceiling-light, notCeiling Light. - No spaces, no
#or+in names, no leading/(it creates an empty first level). - Name rooms as people do, but avoid names that change (
toms-roombecomes awkward when Tom moves out;bedroom-2lasts). - Name devices by function, not brand or model, so you can replace hardware without renaming.
- Reserve a top-level prefix for system topics such as
home1/system/backup-status. - Never put secrets, door codes or personal data in topic names; topics are visible to every subscriber with matching wildcards.
Integrating Ecosystem Topics
You will not control every topic name. Zigbee2MQTT publishes under zigbee2mqtt/<friendly_name>, Tasmota uses stat/, tele/ and cmnd/ prefixes, and Home Assistant discovery uses homeassistant/<component>/<id>/config. Do not fight these conventions. Instead:
- Give devices friendly names that follow your room/device pattern, for example
kitchen/ceiling-lightin Zigbee2MQTT, so its topics becomezigbee2mqtt/kitchen/ceiling-light. - Keep your own DIY devices under your
home1/root. - Let Home Assistant map everything into entities via MQTT discovery.
Our Zigbee2MQTT setup guide shows how friendly names translate into topics.
Try the Layout on a Public Broker
You can test the structure without hardware. Use a random prefix so your topics do not collide with anyone else's:
# Terminal 1: watch the whole house
mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-h7q2 -t "connectmq/demo/h7q2/home1/#" -v
# Terminal 2: a light reports retained state, then a dashboard sends a command
mosquitto_pub -h broker.connectmq.com -p 1883 -i light-h7q2 -r -q 1 \
-t connectmq/demo/h7q2/home1/kitchen/ceiling-light/power -m ON
mosquitto_pub -h broker.connectmq.com -p 1883 -i dash-h7q2 -q 1 \
-t connectmq/demo/h7q2/home1/kitchen/ceiling-light/power/set -m OFF
# Every temperature in the house, any room, any device
mosquitto_sub -h broker.connectmq.com -p 1883 -i temps-h7q2 -t "connectmq/demo/h7q2/home1/+/+/temperature" -v
The demo prefix adds three levels, which is one more reason to keep your own tree shallow. The public area is readable by everyone, so use it for structure experiments only, not for your real home. When you move to a private broker you can drop the demo prefix and start at home1/.
Smart Home Topic Structure Checklist
- Every device follows
<home>/<room>/<device>/<property>. - Commands use a
/setsuffix and are never retained. - States are retained and published by the device after it acts.
- Every device has an
availabilitytopic with a last will. - Names are lowercase, hyphenated and function-based.
- Payload format is documented and consistent.
- Topic depth stays at five levels or fewer.
Running Your Home on a Private Broker
A topic structure only stays clean if the broker it lives on is secure and reliable. ConnectMQ offers a managed MQTT broker with TLS on port 8883, generated credentials and a live topic explorer where your room/device tree is easy to browse. If you are deciding between hosting yourself and using a cloud MQTT broker, think about remote access, certificates and updates. For more home and building projects, see the IoT automation guide.
Get Started with ConnectMQ
Create a free Serverless broker at app.connectmq.com, no credit card required, copy your generated credentials and publish your first home1/ topics. The ConnectMQ live topic explorer shows your whole house as a tree within seconds.
Frequently Asked Questions
Should topics start with a slash?
No. A leading slash creates an empty first level, which is legal but confusing and easy to mistype. Start with your home or site name.
Is it better to use one JSON topic per device or one topic per value?
Both work. One value per topic is simplest for wildcards and DIY devices; JSON per device suits multi-sensor devices. Pick one per device type and document it.
Why is my light turning on by itself after a reboot?
You probably retained a command message. Clear it by publishing an empty retained message to the command topic, and only retain state topics from now on.
How many topic levels should a smart home use?
Four or five is plenty: home, room, device, property and an optional set suffix. Deeper trees add typing and little value.



