Industrial IoT

UNS Topic Structure Examples for Manufacturers

Ready-to-use UNS topic structure examples for discrete manufacturing and process plants, with the naming rules, payload conventions and validation that keep a unified namespace usable as it grows.

Tree diagram of a uns topic structure from enterprise and site down to lines and machines
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

A good UNS topic structure is what makes a unified namespace navigable: anyone who knows the plant can guess where a value lives without opening documentation. This guide gives you ready-to-use topic trees for discrete and process manufacturing, the naming and payload rules that keep them clean, and a small validator you can run in CI or at the gateway to stop bad topics before they reach the broker.

The Principles Behind a UNS Topic Structure

Every example in this article follows the same five principles. If you adapt the trees, keep the principles.

  1. Model the plant, not the technology. Topics describe where something is and what it is, not which protocol or PLC brand produced it. opcua/ and s7/ do not belong in the path.
  2. Hierarchy first, ISA-95 as the backbone. Enterprise, site, area, line or cell, and equipment give a structure operations already understand. The ISA-95 equipment hierarchy guide explains each level.
  3. Fixed depth where possible. When every machine sits at the same level, wildcard subscriptions like +/+/+/+/telemetry work across the whole enterprise.
  4. A small set of leaf types. End each equipment branch in a predictable set of namespaces such as telemetry, state, alarms, events and cmd.
  5. Stable identifiers. Short, lowercase, hyphenated names that survive reorganisations. Asset numbers are often better than descriptive names that change.

Example 1: Discrete Manufacturing

A discrete plant with assembly lines, machining cells and shared utilities:

acme/                                     enterprise
  dallas/                                 site
    machining/                            area
      cell-03/                            work cell
        cnc-01/                           equipment
          telemetry                       {"spindle_rpm":..., "load_pct":..., "ts":...}
          state                           "running" | "idle" | "down" (retained)
          alarms                          active alarm list (retained)
          events/cycle-complete           one message per finished part
          cmd/                            commands, request/response
        robot-01/
          telemetry
          state
    assembly/
      line-02/                            production line
        station-10/
          telemetry
          events/part-scanned
        station-20/
          telemetry
      line-02/kpi/oee                     line-level calculated values
    utilities/
      compressors/
        comp-01/telemetry

Notice the line-level kpi branch. Calculated values such as OEE or throughput belong at the level they describe, published by the application that computes them. This keeps raw machine data and derived data clearly separated while staying in the same tree.

Example 2: Process Manufacturing

Process plants think in process cells and units rather than lines and stations. ISA-95 accommodates both, so the tree changes vocabulary but not shape:

acme/
  izmir/                                  site
    brewing/                              area
      brewhouse-1/                        process cell
        mash-tun/                         unit
          telemetry                       {"temp_c":..., "level_pct":..., "ts":...}
          state                           "heating" | "resting" | "transferring"
          batch                           current batch id and recipe (retained)
        lauter-tun/
          telemetry
      fermentation/
        fv-07/
          telemetry
          batch
    utilities/
      boiler-1/telemetry
      water-treatment/ro-1/telemetry

The batch leaf is the process-plant equivalent of a work order: retained, small, and updated when the batch changes. Consumers join batch context with telemetry by topic path, without a separate database lookup.

Example 3: Multi-Site Enterprise With Shared Services

When several sites share a broker or a bridged namespace, add a top-level branch for enterprise systems so that MES, ERP and quality data have a home that does not pretend to be equipment:

acme/dallas/...                           site trees as above
acme/izmir/...
acme/_enterprise/erp/work-orders/dallas   work orders per site (retained)
acme/_enterprise/quality/spc/dallas/line-02
acme/_enterprise/mes/schedule/izmir

The leading underscore keeps the branch sorted apart from site names and makes it obvious that it is not a physical location.

How Sparkplug B Fits a UNS Topic Structure

Sparkplug B uses its own fixed topic format, spBv1.0/<group>/<message type>/<edge node>/<device>. That format is optimised for state management between edge nodes and host applications, not for browsing by plant hierarchy. Our Sparkplug topic namespace article explains it in full.

You do not need to choose. A common pattern keeps Sparkplug for edge-to-host traffic and republishes values into the ISA-95 tree for everyone else. ConnectMQ does this automatically for Sparkplug B traffic: it decodes the Protobuf or JSON payload and republishes into ISA-95 topics, so spBv1.0/factory1/DDATA/line1/cnc1 becomes connectmq/factory1/production/line1/cnc1/telemetry. Dashboards and historians subscribe to readable JSON in the ISA-95 tree, while SCADA hosts keep using native Sparkplug.

Naming and Payload Rules

Rule Good Avoid
Lowercase only line-02 Line_02, LINE02
Hyphens, no spaces mash-tun mash tun, mash%20tun
No leading or trailing slash acme/dallas/... /acme/dallas/
No wildcard or $ characters in names cnc-01 cnc#1, $cnc
Units in field names temp_c, speed_bpm temp, speed
Timestamps in payloads "ts": "2026-10-16T08:00:00Z" Relying on arrival time
Retain current state state, batch, alarms Retaining event streams
Version payloads "v": 2 Silent breaking changes

A leading slash is a classic mistake: it creates an empty first level, so /acme/# and acme/# are different subscriptions. Mixed case is another: MQTT topics are case sensitive, and Line-02 and line-02 become two different branches that quietly split your data.

Validate Topics Before They Reach the Broker

The script below checks topics against the rules above and the five-level equipment structure. Use it in a gateway, in a CI test over your tag mapping file, or as a monitoring subscriber that reports violations.

import re

LEVEL = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
LEAVES = {"telemetry", "state", "alarms", "batch", "events", "cmd", "kpi"}

def validate(topic: str, depth: int = 5) -> list[str]:
    """Return a list of problems; an empty list means the topic is valid."""
    problems = []
    if topic.startswith("/") or topic.endswith("/"):
        problems.append("leading or trailing slash")
    levels = topic.strip("/").split("/")
    if any(ch in topic for ch in "+#$"):
        problems.append("wildcard or $ character in topic name")
    if any(" " in level for level in levels):
        problems.append("space in topic level")
    if len(levels) < depth + 1:
        problems.append(f"expected at least {depth + 1} levels, got {len(levels)}")
        return problems
    for level in levels[:depth]:
        if not (LEVEL.match(level) or level.startswith("_")):
            problems.append(f"level '{level}' is not lowercase-hyphenated")
    if levels[depth] not in LEAVES:
        problems.append(f"leaf '{levels[depth]}' not in {sorted(LEAVES)}")
    return problems

if __name__ == "__main__":
    tests = [
        "acme/dallas/machining/cell-03/cnc-01/telemetry",
        "acme/dallas/machining/cell-03/CNC_01/telemetry",
        "/acme/dallas/assembly/line-02/station-10/telemetry",
        "acme/dallas/assembly/line-02/station-10/temperature",
    ]
    for t in tests:
        result = validate(t)
        print("OK  " if not result else "FAIL", t, "" if not result else result)

Run it with python validate_topics.py and adjust LEAVES and depth to match your standard.

Evolving the Structure Without Breaking Consumers

No topic structure survives contact with a real plant unchanged. Lines are rebuilt, machines move between cells, a new site is acquired with its own naming habits. The goal is not to avoid change but to make it safe.

  1. Add, never rename in place. When a branch must change, publish to the new path and the old path in parallel for a defined period, then retire the old one. Announce the sunset date to every consumer owner.
  2. Clear retained messages on retirement. A retired branch still returns retained values to new subscribers. Publish an empty retained message to each old state topic to remove it.
  3. Keep a registry. A simple file in version control listing every branch, its owner, its leaf types and its payload schema version is enough. The validator above can read its rules from that file.
  4. Version payloads, not topics. Put a v field in the payload when the schema changes. Topics with /v2/ in the path tend to multiply and confuse wildcard subscriptions.
  5. Review new branches. A short review by the namespace owner before a gateway goes live catches most problems while they are still cheap to fix.

Treat the structure like an API that the whole plant depends on, because that is exactly what it becomes once dashboards, historians and MES integrations subscribe to it.

Try the Structure on a Live Broker

Before rolling a structure out, publish a few sample messages and browse them. On the public MQTT test broker at broker.connectmq.com you can do this without an account, as long as you use a unique prefix and remember that the public area is readable by everyone. The public broker allows 8 topic levels, so connectmq/demo/<id>/ plus the five-level tree and a leaf fits exactly when you drop the enterprise level:

mosquitto_pub -h broker.connectmq.com -p 1883 -i uns-test-pub-q7 -r \
  -t "connectmq/demo/q7w2/dallas/machining/cell-03/cnc-01/state" -m "running"

mosquitto_sub -h broker.connectmq.com -p 1883 -i uns-test-sub-q7 \
  -t "connectmq/demo/q7w2/dallas/+/+/+/state" -v

On a private ConnectMQ broker you can use the full tree without the demo prefix, and the portal's live topic explorer and ISA-95 devices view show at a glance whether devices land at the right enterprise, site, area and line. For step-by-step encoding rules, continue with ISA-95 MQTT topics, and for the full build process see how to build a unified namespace. The wider picture is in our industrial IoT MQTT guide.

Put Your UNS Topic Structure on ConnectMQ

A topic structure is only as good as the broker that carries it and the visibility you have into it. ConnectMQ is a fully managed MQTT service that detects ISA-95 and unified namespace topics, decodes Sparkplug B and republishes it into your ISA-95 tree. Create a broker on the free Serverless plan at app.connectmq.com, no credit card required, and publish your first namespace branch in minutes.

Frequently Asked Questions

How many levels should a UNS topic structure have?

Most plants use five or six: enterprise, site, area, line or cell, equipment, and a leaf such as telemetry or state. Fixed depth keeps wildcard subscriptions simple.

Should each metric get its own topic?

Both approaches work. One JSON object per equipment telemetry topic is simpler and cheaper; a topic per metric suits tools that map topics directly to tags. Pick one per leaf type and apply it consistently.

Where do calculated KPIs belong?

At the level they describe, published by the application that computes them, for example a kpi/oee branch under the line.

Can Sparkplug B topics be part of a UNS?

Yes, but they are not organised by plant hierarchy. Republish Sparkplug values into ISA-95 topics so all consumers can browse one tree.

Related articles

IIoT Edge Gateway: What It Does and How to Choose One

An IIoT edge gateway connects machines that speak Modbus, OPC UA or proprietary protocols to MQTT and the cloud. Learn its core roles, common architectures and how to choose the right one.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.