Understanding MQTT Topics

MQTT Topics are structured in a hierarchy similar to folders and files in a file system using the forward slash ( / )as a delimiter.

Using this system you can create a user friendly and self descriptive naming structures of you own choosing.

Topic names are:

  • Case sensitive
  • use UTF-8 strings.
  • Must consist of at least one character to be valid.

Except for the $SYS topic there is no default or standard topic structure.

That is there are no topics created on a broker by default, except for the $SYS topic.

All topics are created by a subscribing or publishing client, and they are not permanent.

A topic only exists if a client has subscribed to it, or a broker has a retained or last will messages stored for that topic.

The $SYS topic

This is a reserved topic and is used by most MQTT brokers to publish information about the broker.

They are read-only topics for the MQTT clients. There is no standard for this topic structure but there is a guideline here that most broker implementations seem to follow.

Here is a Mosquitto dashboard that displays data published over the $SYS topic by mosquitto. The code is here.

Subscribing to Topics

A client can subscribe to individual or multiple topics.

When subscribing to multiple topics two wildcard characters can be used. The are:

  • # (hash character) – multi level wildcard
  • + (plus character) -single level wildcard

Wildcards can only be used to denote a level or multi-levels i.e /house/# and not as part of the name to denote multiple characters e.g. hou# is not valid

Topic naming Examples:

Valid Topic subscriptions

Single topic subscriptions

  • /
  • /house
  • house/room/main-light
  • house/room/side-light

Using Wildcards

Subscribing to topic house/#

Covers

  • house/room1/main-light
  • house/room1/alarm
  • house/garage/main-light
  • house/main-door
  • etc

Subscribing to topic house/+/main-light

covers

  • house/room1/main-light
  • house/room2/main-light
  • house/garage/main-light

but doesn’t cover

  • house/room1/side-light
  • house/room2/side-light

Invalid Topic Subscriptions

  • house+ – Reason- no topic level
  • house# – Reason- no topic level

Publishing to Topics

A client can only publish to an individual topic. That is, using wildcards when publishing is not allowed.

E.G- To publish a message to two topics you need to publish the message twice

When are Topics Created

Topics are created dynamically when:

  • Someone subscribes to a topic
  • Someone publishes a message to a topic with the retained message set to True.

When are Topics Removed from a Broker

  • When the last client that is subscribing to that broker disconnects, and clean session is true.
  • When a client connects with clean session set to True.

Video

Here is a video that covers the basics of MQTT topics.

Republishing Topic Data

This is likely to be done when changing or combining naming schemes.

The idea is that a client would subscribe to a topic, e.g.

hub1/sensor1 and republish the data using a new topic naming of house1/main-light.

Common Questions and Answers

Q- How do I subscribe to all topics?

A-Subscribe to #

Q- How Do I subscribe to all $SYS topics?

A-Subscribe to $SYS/#

Q- Should I start my Topic hierarchy with a /.

A- It is not necessary and just adds another level to the structure.

Q- Can I get list of all topics on a broker?

A- Not unless you subscribe to all topics and scan them.

Q- Can I tell who is subscribed to a topic?

A– No

Q- How do I discover topics?

A- There is currently no mechanism for that except as described in list all topics.

Related Tutorials and Resources:

Facebooktwittergoogle_plusredditpinterestlinkedinmail

4 comments

  1. Hello Steve,

    first thanks for all the info. But I wonder, are usually topics implemented to be able to retrieve their levels?

    For example, with JS or Python Paho implementations of MQTT Client, if I were to send the ClientID as part of a topic (ping/clientID) for a ping subscription (ping/+), should I be able to retrieve the clientID easily, or would I have to split the topic as a string?

    Sorry for the specific question, but it strikes me as weird that something like this isn’t a little better implemented (why have a topic hierarchy if you are not going to have an specific object for it?).

    1. You would have to split the topic.
      With MQTT the sender and receiver aren’t aware of each other as there is no connection between the two. When a client receives a message it doesn’t have any idea of which client sent it unless the sender includes that information in the topic or message payload.

Leave a Reply

Your email address will not be published. Required fields are marked *