Topics in MQTT use a hierarchical structure with / separators. This chapter covers best practices for designing topic hierarchies that scale and support efficient wildcard subscriptions.
Use Wildcards Effectively: Apply + and # wildcards for flexible subscriptions
Avoid Common Mistakes: Prevent topic naming pitfalls that cause issues
Optimize for Performance: Balance topic depth with broker efficiency
1199.3 Topic Hierarchy Fundamentals
Graph diagram
Figure 1199.1: MQTT topic hierarchy design showing location-based organization with home/living_room/temperature structure, wildcard subscription patterns using plus sign for single-level and hash for multi-level matching, and best practice rules including lowercase naming, underscore separators, hierarchical structure, avoiding leading slashes and spaces, with maximum 5-7 hierarchy levels.
Best Practices:
Use descriptive, hierarchical names
Keep topics lowercase
Avoid spaces (use underscores)
Include location/device/measurement
Don’t start with /
Avoid deep nesting (max 5-7 levels)
1199.4 Wildcard Patterns
NoteUnderstanding Wildcards
+ (Single-level wildcard): Matches any value at a single topic level
home/+/temperature matches home/bedroom/temperature and home/kitchen/temperature
Does NOT match home/bedroom/sensor/temperature (too many levels)
# (Multi-level wildcard): Matches zero or more levels
home/# matches everything under home/
Must be the last character in subscription
home/bedroom/# matches home/bedroom/temperature and home/bedroom/sensor/data
Performance Tip: Specific subscriptions are faster than wildcards. Use home/bedroom/temperature instead of home/+/+ when possible.
Show code
{const container =document.getElementById('kc-mqtt-3');if (container &&typeof InlineKnowledgeCheck !=='undefined') { container.innerHTML=''; container.appendChild(InlineKnowledgeCheck.create({question:"A building automation system has sensors organized as: building/floor1/room101/temperature, building/floor1/room102/temperature, building/floor2/room201/temperature. A dashboard needs to display temperatures from ALL rooms on floor 1 only. Which subscription pattern should be used?",options: [ {text:"building/floor1/#",correct:false,feedback:"Close, but this subscribes to ALL topics under floor1, including humidity, motion, lights, etc. If you only want temperature readings, this would receive too many messages and require filtering on the client side."}, {text:"building/floor1/+/temperature",correct:true,feedback:"Correct! The '+' wildcard matches exactly one topic level, so this subscribes to building/floor1/room101/temperature, building/floor1/room102/temperature, etc. It correctly filters to temperature only and floor 1 only."}, {text:"building/+/+/temperature",correct:false,feedback:"Incorrect. This would match temperatures from ALL floors (floor1, floor2, etc.), not just floor 1. The '+' at the floor level would match any floor."}, {text:"building/floor1/room+/temperature",correct:false,feedback:"Incorrect. MQTT wildcards '+' and '#' must occupy an entire topic level between slashes. 'room+' is not valid syntax - you cannot combine text with wildcards within a single level."} ],difficulty:"medium",topic:"mqtt-wildcards" })); }}
Show code
{const container =document.getElementById('kc-mqtt-4');if (container &&typeof InlineKnowledgeCheck !=='undefined') { container.innerHTML=''; container.appendChild(InlineKnowledgeCheck.create({question:"An IoT architect is designing topic structure for a smart city deployment with 1000+ streetlights. Which topic structure follows MQTT best practices?",options: [ {text:"/city/District A/streetlight_001/status",correct:false,feedback:"Incorrect. This violates multiple best practices: starts with '/' (creates empty root level), uses spaces in 'District A', and mixed case. These issues waste bandwidth and complicate client implementations."}, {text:"city/district_a/streetlights/light_001/status",correct:true,feedback:"Correct! This follows all best practices: no leading slash, lowercase letters, underscores instead of spaces, hierarchical structure (city > district > device type > device ID > metric), and reasonable depth (5 levels)."}, {text:"streetlight_001_status",correct:false,feedback:"Incorrect. This flat structure prevents using wildcards for efficient subscriptions. You couldn't easily subscribe to all lights in a district or all status updates. Hierarchical topics enable flexible subscription patterns."}, {text:"city/region/district/zone/subzone/street/pole/light/status",correct:false,feedback:"Incorrect. This topic is too deeply nested (9 levels). Deep nesting impacts broker performance, increases message size, and makes topics harder to read. MQTT recommends 5-7 levels maximum."} ],difficulty:"easy",topic:"mqtt-topic-design" })); }}
1199.5 Deep Dive: Topic Design Best Practices
NoteDeep Dive: Topic Design Best Practices
Designing your MQTT topic hierarchy is like designing a database schema-do it right at the start or suffer later.
BAD: lights/living_room (used for both commands and state)
GOOD: lights/living_room/command (set desired state)
GOOD: lights/living_room/state (actual current state)
$SYS/broker/clients/connected -> Broker publishes system info
$SYS/broker/messages/received -> Message statistics
Topics starting with $ are reserved for broker internal use.
Performance Considerations:
Topic Depth
Wildcard Matching Speed
Memory Usage
3 levels
Fast (microseconds)
Low
5 levels
Moderate
Moderate
10 levels
Slow (milliseconds)
High
Real-World Example: AWS IoT Core Topics:
$aws/things/{thing-name}/shadow/update -> Device updates
$aws/things/{thing-name}/shadow/update/accepted -> Cloud confirms
$aws/things/{thing-name}/shadow/get -> Request current state
Migration Strategy:
If you need to change topic structure in production: 1. Publish to both old and new topics (6 months) 2. Update subscribers gradually 3. Monitor old topic usage (zero activity?) 4. Deprecate old topics (send final migration notice) 5. Remove old topic publishing
Topic Naming Conventions Document:
# MQTT Topic Standards v2.1## Format{domain}/{location}/{device_type}/{device_id}/{metric}## Examples- factory/building_a/temperature/sensor_001/celsius- home/bedroom/light/bulb_12/state## Wildcards- `+` matches one level: `home/+/temperature`- `#` matches all levels: `home/bedroom/#`## Reserved Prefixes- `$SYS/` - Broker system topics (read-only)- `$aws/` - AWS IoT Core (if using AWS)## ACL Template- Devices: write to `{domain}/{location}/{device_type}/{device_id}/#`- Dashboards: read from `{domain}/#`
Invest time in topic design-changing it later is painful!
1199.6 Worked Example: Smart Factory Topic Design
NoteWorked Example: MQTT Topic Hierarchy Design for Smart Factory
Scenario: A manufacturing plant needs to deploy 500 sensors across 4 production lines, each with 25 machines containing 5 sensors (temperature, vibration, current, pressure, and status).
Given:
4 production lines (line_a through line_d)
25 machines per line (machine_001 through machine_025)
5 sensors per machine (temp, vibration, current, pressure, status)
Dashboard needs all data; maintenance teams need per-line views; safety system needs all pressure readings
Single machine: factory/line_a/machine_012/# - receives 5 msg/sec
Calculate broker subscription table size:
500 unique topics + 4 wildcard patterns
Memory per subscription: ~200 bytes (topic string + metadata)
Total: 504 x 200 bytes = 100.8 KB subscription table
Result: Topic hierarchy enables flexible subscriptions with 17.5 KB/sec topic overhead. Dashboard uses 1 subscription instead of 500 individual subscriptions. Maintenance team subscribes to 1 wildcard pattern instead of 125 topics. Safety system monitors 100 pressure sensors with single +/+/pressure pattern.
Key Insight: Hierarchical topic design with 3-5 levels balances flexibility against broker memory. Each wildcard level adds ~50 microseconds matching time - at 500 msg/sec, the factory’s 4 wildcard subscriptions add 100 microseconds total routing delay (negligible). Flatter hierarchies (line_a_machine_012_temp) prevent wildcard use and force explicit subscription lists.
1199.7 MQTT Broker Game
Master MQTT concepts through an interactive game where you act as an MQTT broker, routing messages from publishers to the correct subscribers. See the full MQTT Labs chapter for the complete interactive game with three difficulty levels.
1199.8 Knowledge Check
Question: Your smart home has 50 sensors. Dashboard subscribes to all using individual topics: home/sensor1/temp, home/sensor2/temp, …, home/sensor50/temp. This requires 50 SUBSCRIBE messages. How can you optimize?
Explanation: MQTT wildcards enable efficient multi-topic subscriptions. Wildcards: (1) + (single-level): Matches one topic level. home/+/temp matches home/sensor1/temp, home/living_room/temp, NOT home/bedroom/closet/temp, (2) # (multi-level): Matches zero or more levels. home/# matches ALL topics under home: home/temp, home/bedroom/light, home/bedroom/closet/humidity. Your solution: client.subscribe("home/+/temp") receives ALL sensor temperatures with 1 subscription vs 50. Benefits: (1) Reduced broker load (1 subscription entry vs 50), (2) Dynamic sensors (new sensor42 automatically included), (3) Lower memory (client tracks 1 subscription vs 50), (4) Faster connection (1 SUBSCRIBE message vs 50).
1199.9 What’s Next
Continue to MQTT QoS Levels to understand the three Quality of Service levels and their impact on reliability, battery life, and performance.