14  MQTT Topic Design and Wildcards

In 60 Seconds

MQTT topics use /-separated hierarchical names (e.g., factory/line_a/machine_001/temperature) with two subscription wildcards: + matches one level and # matches all remaining levels. Design topics with 3-5 levels following a {domain}/{location}/{device}/{metric} pattern, never start with /, and plan your hierarchy before deployment since changing it requires coordinated migration across all publishers and subscribers.

14.1 Introduction

⏱️ ~15 min | ⭐⭐ Intermediate | 📋 P09.C05.U01

Key Concepts

  • Topic: UTF-8 string hierarchy (e.g., sensors/building-A/room-101/temperature) routing messages to subscribers
  • Topic Level: Segment between / separators — each level represents a dimension of the topic hierarchy
  • Single-Level Wildcard (+): Matches exactly one topic level: sensors/+/temperature matches sensors/room1/temperature
  • Multi-Level Wildcard (#): Matches remaining levels: sensors/# matches all topics starting with sensors/
  • Retained Message: Last message stored per topic — new subscribers immediately receive current state on subscription
  • Topic Hierarchy Design: Best practice: device-type/device-id/measurement enables fine-grained subscription filtering
  • $SYS Topics: Reserved broker system topics (e.g., $SYS/broker/clients/connected) publishing broker statistics

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. A well-designed topic structure enables efficient message routing, simplifies access control, and scales gracefully as your IoT deployment grows.

Learning Objectives

By the end of this chapter, you will be able to:

  • Design and Construct Topic Hierarchies: Build scalable, maintainable topic structures following the {domain}/{location}/{device}/{metric} pattern
  • Apply and Compare Wildcard Patterns: Select the appropriate + or # wildcard for a given subscription scenario and justify the choice
  • Diagnose Topic Naming Errors: Identify anti-patterns such as leading slashes, spaces, and excessive depth, and correct them
  • Evaluate Subscription Strategies: Assess the bandwidth, memory, and performance trade-offs between individual subscriptions and wildcard subscriptions
MVU: MQTT Topic Wildcards

Core Concept: MQTT uses two wildcards for subscriptions: + matches exactly one topic level (single-level), while # matches zero or more levels (multi-level) and must appear at the end. Topic hierarchies use / as separators.

Why It Matters: A poorly designed topic structure forces clients to subscribe individually to hundreds of topics, wasting bandwidth and broker memory. With a hierarchical design like factory/line_a/machine_001/temperature, a dashboard can subscribe to factory/# for everything, maintenance to factory/line_a/# for one line, or safety systems to factory/+/+/pressure for all pressure sensors. One wildcard subscription replaces potentially thousands of individual subscriptions.

Key Takeaway: Design topics with 3-5 levels following {domain}/{location}/{device}/{metric} pattern. Use + for specific level filtering and # for subtree subscriptions. Never start topics with / (wastes bandwidth) or use spaces (breaks parsing). Plan your topic structure before deployment - changing it later requires coordinated migration across all publishers and subscribers.

14.2 Prerequisites

Before diving into this chapter, you should be familiar with:

  • MQTT Fundamentals: Understanding the publish-subscribe pattern, brokers, and basic message flow
  • MQTT Architecture: Knowledge of MQTT components and how publishers/subscribers interact via brokers

Think of MQTT topics like a filing system for messages. Just as you organize files in folders like Documents/Work/Reports/2025, MQTT organizes messages in topics like home/bedroom/temperature.

Why does this matter?

Without topics, every subscriber would receive EVERY message from every device - imagine getting emails meant for everyone in your company! Topics let subscribers filter to receive only the messages they care about.

Topic Structure:

  • Topics use / to separate levels: home/bedroom/temperature
  • Each level adds specificity: homebedroomtemperature
  • Topics are case-sensitive: Home/Bedroomhome/bedroom

Wildcards - The Power Feature:

Instead of subscribing to each room individually: - home/bedroom/temperature - home/kitchen/temperature - home/bathroom/temperature

You can use a wildcard: - home/+/temperature - matches ALL rooms!

Term Simple Explanation
Topic An address for messages, like a radio channel
Level Each part between / separators
+ Wildcard Matches any ONE level (single-level wildcard)
# Wildcard Matches any NUMBER of levels (multi-level wildcard)
Subscribe Tell the broker which topics you want to receive
Publish Send a message to a specific topic

Topics are like addresses for sensor messages!

14.2.1 The Sensor Squad Adventure: Message Sorting

Welcome to the MQTT Post Office, where Sammy and friends learn to sort sensor messages!

Postmaster Perry runs the MQTT broker - the smartest post office ever. “Every message needs an address,” Perry explains. “We call these addresses TOPICS. They help me know where to deliver each message.”

Sammy the Sensor sends temperature readings from the bedroom. “My messages go to home/bedroom/temperature. It’s like my mailing address! Home is my neighborhood, bedroom is my street, and temperature is my house number.”

Lila the Light Sensor works in the garden. “I send to home/garden/light. Same neighborhood (home), different street (garden), different house (light)!”

Dashboard Danny wants ALL the sensor data. “I can’t remember everyone’s address,” Danny sighs. “There are too many sensors!”

Postmaster Perry winks. “Use the magic wildcards! Subscribe to home/# and you’ll get messages from EVERY sensor in the home. The # means ‘everything from here onwards’!”

Max the Motion Detector has a challenge: “I only want to know about temperatures in ALL rooms, not lights or motion.”

Perry teaches him: “Use home/+/temperature. The + means ‘any single word here’. So you’ll get home/bedroom/temperature, home/kitchen/temperature, home/garden/temperature - but NOT home/bedroom/light!”

Bella the Battery Monitor learned an important lesson: “I accidentally named my topic home/ bedroom/temperature with a space. Nobody could find my messages! Spaces break the address system.”

14.2.2 Key Words for Kids

Word What It Means
Topic The address where sensor messages get delivered
Level Each word in the address, separated by /
+ Plus Wildcard Magic word meaning “any single word goes here”
# Hash Wildcard Magic word meaning “everything from here to the end”
Subscribe Telling the post office which addresses you want mail from

14.2.3 Try This at Home!

Be a Topic Designer!

Design topics for a smart home with these devices: 1. Temperature sensor in the living room 2. Motion detector in the hallway 3. Light switch in the kitchen

Example: home/living_room/temperature

Now try to create ONE wildcard subscription that gets ALL motion sensors in the house! Answer: home/+/motion


14.3 Topic Hierarchy Fundamentals

MQTT topics form a tree-like hierarchy where each level is separated by /. This structure enables powerful wildcard subscriptions and logical organization of your IoT data.

Topic hierarchy tree

MQTT topic hierarchy showing hierarchical organization from domain to specific metrics
Figure 14.1: MQTT topic hierarchy showing hierarchical organization from domain to specific metrics

Example Full Topic Paths:

  • home/living_room/thermostat/temperature - Living room temperature reading
  • home/bedroom/thermostat/humidity - Bedroom humidity reading
  • factory/line_a/machine_001/vibration - Machine vibration sensor data

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)

14.4 Wildcard Patterns

MQTT provides two powerful wildcards for flexible subscriptions:

Wildcard matching patterns

MQTT wildcard matching: + matches single level, # matches multiple levels
Figure 14.2: MQTT wildcard matching: + matches single level, # matches multiple levels
Understanding 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.

How much network traffic can wildcard subscriptions save? Let’s quantify the benefits of using + and # versus individual subscriptions.

Scenario: Monitor 50 temperature sensors in 10 buildings.

Individual subscriptions approach (one SUBSCRIBE per sensor): \(\text{Subscriptions} = 50\text{ sensors} = 50\text{ SUBSCRIBE packets}\) \(\text{Packet overhead} \approx 2\text{ bytes (fixed header)} + 2\text{ bytes (packet ID)} + 2\text{ bytes (length field)} + 25\text{ bytes (topic)} + 1\text{ byte (QoS)} = 32\text{ bytes/packet}\) \(\text{Total traffic} = 50 \times 32 = 1{,}600\text{ bytes}\)

Single-level wildcard approach (building/+/temperature — one subscription for all buildings): \(\text{Subscriptions} = 1\text{ SUBSCRIBE packet}\) \(\text{Packet overhead} \approx 32\text{ bytes (same structure, slightly longer topic)}\) \(\text{Bandwidth savings} = \frac{1{,}600 - 32}{1{,}600} \times 100\% = 98\%\)

Multi-level wildcard approach (building/# — one subscription for all data): \(\text{Subscriptions} = 1\text{ SUBSCRIBE packet}\) \(\text{Traffic} \approx 32\text{ bytes (shorter topic string)}\) \(\text{Bandwidth savings} = \frac{1{,}600 - 32}{1{,}600} \times 100\% = 98\%\)

Broker memory impact: Each subscription entry consumes ~200 bytes of RAM (topic string + trie node metadata). Wildcard approach: \(200 \times 1 = 200\text{ bytes}\) vs individual: \(200 \times 50 = 10{,}000\text{ bytes}\) (98% memory reduction).

Key insight: A single wildcard subscription replaces all 50 individual subscriptions, reducing setup traffic by 98% and broker memory by 98%. New sensors are automatically covered without any client update.

Calculate the bandwidth and memory savings from using wildcard subscriptions:

14.5 Topic Design Decision Framework

Choosing the right topic structure involves balancing several competing concerns. Use this decision framework:

Topic design decision tree

Decision framework for MQTT topic design showing trade-offs between depth, wildcards, and performance
Figure 14.3: Decision framework for MQTT topic design showing trade-offs between depth, wildcards, and performance

14.6 Deep 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.

Hierarchical Topic Structure:

{domain}/{location}/{device_type}/{device_id}/{metric}

Good Examples:

factory/building_a/temperature/sensor_001/celsius
factory/building_a/temperature/sensor_001/humidity
factory/building_a/conveyor/motor_012/rpm
factory/building_a/conveyor/motor_012/current
home/living_room/thermostat/nest_01/temperature
home/living_room/thermostat/nest_01/target_temp

Why This Structure Works:

  1. Wildcard Efficiency:
    • All building_a data: factory/building_a/#
    • All temperature sensors: factory/+/temperature/#
    • Specific sensor: factory/building_a/temperature/sensor_001/#
  2. ACL Mapping:
    • Sensor can only publish to its own topics: factory/building_a/temperature/sensor_001/#
    • Dashboard reads all: factory/#
    • Mobile app reads one building: factory/building_a/#
  3. Scalability:
    • Add new building: factory/building_b/... (no code changes)
    • Add new metric: factory/building_a/temperature/sensor_001/battery (subscribers see it)

Common Mistakes:

  1. Starting with /:

    BAD: /home/bedroom/temp
    GOOD: home/bedroom/temp

    Leading / creates empty root level (wastes bandwidth)

  2. Spaces and Special Characters:

    BAD: home/Living Room/temp
    BAD: home/bedroom/temp(celsius)
    GOOD: home/living_room/temp_celsius

    Use underscores, lowercase, avoid parentheses/spaces

  3. Too Flat:

    BAD: sensor_001_temp
    BAD: sensor_002_temp
    GOOD: sensors/001/temp
    GOOD: sensors/002/temp

    Can’t use wildcards efficiently

  4. Too Deep:

    BAD: company/headquarters/building/floor/room/zone/device/sensor/metric
    GOOD: hq/floor3/room_301/sensor_12/temp

    Max 5-7 levels recommended (broker performance)

  5. Mixing Commands and State:

    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)

    Separate concerns for clarity

Advanced Patterns:

Command-State Pattern:

devices/{device_id}/command/set_temp  -> Controller publishes
devices/{device_id}/state/current_temp -> Device publishes
devices/{device_id}/state/target_temp  -> Device confirms

Metadata Topics:

devices/{device_id}/status     -> "online"/"offline" (LWT)
devices/{device_id}/config     -> Device configuration (retained)
devices/{device_id}/telemetry  -> Battery, signal strength, uptime

Reserved Topics:

$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!

14.7 Wildcard Comparison and Use Cases

Understanding when to use each wildcard type is crucial for efficient subscription management:

Wildcard type comparison

Comparison of MQTT wildcard types showing matching behavior and common use cases
Figure 14.4: Comparison of MQTT wildcard types showing matching behavior and common use cases

Wildcard Selection Guide:

Scenario Recommended Pattern Reason
All temperatures in building building/+/temperature Filter to specific metric
All data from one room home/bedroom/# Get entire subtree
All sensors, all rooms home/+/+/data Two wildcards for 2 variable levels
Everything (debugging) # Receives ALL messages

14.8 Worked Example: Smart Factory Topic Design

Worked 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).

Factory hierarchy example

Smart factory topic hierarchy showing 4 production lines with 500 sensors and wildcard subscription patterns
Figure 14.5: Smart factory topic hierarchy showing 4 production lines with 500 sensors and wildcard subscription patterns

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
  • Expected message rate: 1 message/sensor/second = 500 messages/second

Steps:

  1. Design hierarchical topic structure:

    factory/{line}/{machine}/{sensor_type}

    Example: factory/line_a/machine_012/temperature

  2. Calculate topic string overhead:

    • Average topic length: 35 characters = 35 bytes per message
    • At 500 msg/sec: 35 x 500 = 17,500 bytes/sec = 17.5 KB/sec topic overhead
  3. Define wildcard subscription patterns:

    • Dashboard (all data): factory/# - single subscription, receives 500 msg/sec
    • Line maintenance: factory/line_a/# - receives 125 msg/sec (25 machines x 5 sensors)
    • Safety system: factory/+/+/pressure - receives 100 msg/sec (4 lines x 25 machines)
    • Single machine: factory/line_a/machine_012/# - receives 5 msg/sec
  4. 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.

Calculate the bandwidth consumed by topic names in your MQTT deployment:

14.9 Common Pitfalls and Anti-Patterns

Common Topic Design Mistakes

Avoid these common mistakes that cause problems in production:

Topic design pitfalls

Common MQTT topic design pitfalls with correct alternatives
Figure 14.6: Common MQTT topic design pitfalls with correct alternatives
Pitfall Impact Solution
Leading / Creates empty root level, wastes 1 byte per message Remove the leading slash
Spaces in topics Breaks URL encoding, complicates client code Use underscores: living_room
Flat structure Cannot use wildcards efficiently Add hierarchy: domain/location/device/metric
Too deep (>7 levels) Broker performance degrades, topics hard to read Flatten to 4-5 meaningful levels
Mixed commands/state Ambiguous message direction, ACL complexity Separate: /command and /state topics

14.10 Concept Matching and Sequencing Practice

Practice: Match Concepts and Order the Steps

Test your understanding of MQTT topic concepts by matching terms to their definitions, then practice ordering the steps for deploying a topic hierarchy.

14.11 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.

14.12 Knowledge Check

14.13 Summary

In this chapter, you learned about MQTT topic design and wildcard subscriptions:

Topic Hierarchy Design:

  • Topics use / as level separators: home/bedroom/temperature
  • Follow the pattern: {domain}/{location}/{device}/{metric}
  • Use lowercase, underscores (no spaces), and 3-5 levels maximum
  • Never start topics with / (creates empty root level)
  • Separate commands and state: device/command vs device/state

Wildcard Subscriptions:

  • + (single-level): Matches exactly one level - home/+/temperature
  • # (multi-level): Matches zero or more levels - home/#
  • # must be the last character in a subscription
  • Wildcards reduce subscription count from hundreds to one

Performance Considerations:

  • Specific subscriptions are faster than wildcards
  • Topic depth of 3-5 levels balances flexibility with broker efficiency
  • Each wildcard level adds ~50 microseconds matching time

Key Design Principles:

  • Plan your topic structure before deployment
  • Consider ACL (access control) requirements when designing hierarchy
  • Document your topic naming conventions for the team
  • Migration after deployment requires coordinated publisher/subscriber updates

14.14 What’s Next

Chapter Focus Why Read It
MQTT QoS Levels Quality of Service 0, 1, and 2 Understand how delivery guarantees interact with your topic design — retained messages and persistent sessions depend on QoS
MQTT Architecture Broker internals and pub-sub pattern See how the broker routes messages using the topic tree you designed in this chapter
MQTT Security Authentication, TLS, and topic ACLs Learn how to restrict publish/subscribe permissions to specific topic patterns using access control lists
MQTT Retained Messages Retained message flags Discover how retained messages combine with topic hierarchies to deliver the last known value to new subscribers
MQTT Last Will and Testament Device offline detection See how LWT topics are designed using the same hierarchy patterns covered here
MQTT Labs Hands-on practice Apply wildcard patterns in a live broker environment and play the MQTT broker routing game

14.15 See Also