Solace Messaging Explained: Topics, Queues and Delivery Modes
Solace Topic Hierarchy and Wildcards: Designing Topics for a Plant
Solace topic hierarchy explained: levels, the * and > wildcards, exceptions and limits, plus a worked ISA-95 topic tree with good and bad examples.
A Solace topic hierarchy is the structure of slash-separated levels, such as mfg/machine/stateChanged/v1/mtl/packaging/line3/filler, that every message carries and every subscription filters on. The broker matches topics against subscriptions level by level, and the wildcards * (one level) and > (one or more trailing levels) let a consumer select a whole family of topics with one pattern. Because consumers choose data by pattern, the hierarchy is the real interface of an event-driven plant: design it well and new consumers cost nothing; design it badly and every new use case needs a new subscription list or a republish.
This page covers the rules, then works through a plant topic tree built on the ISA-95 equipment hierarchy. It belongs to the Solace messaging model in the Solace cluster.
The rules of a Solace topic hierarchy
Solace’s SMF topics page sets the structure:
| Rule | What the docs say | Why it matters in a plant |
|---|---|---|
| Length | Maximum 250 bytes, excluding the null terminator | Long site and equipment names add up; bytes, not characters |
| Depth | Maximum 128 levels | Never the constraint in practice; consistency is |
| Case | Case-sensitive: Line3 is not line3 | One stray capital splits a stream in two |
| Characters | All UTF-8 except null | Allowed is not advisable; avoid spaces and symbols |
* in a subscription | Matches one level; after a prefix, matches the prefix plus anything in that level | line* selects every line without listing them |
> in a subscription | Matches one or more levels, only alone at the last level | .../mtl/> selects everything below Montreal |
! on a queue subscription | A subscription exception | Keeps a test cell out of a production queue |
| Reserved | Topics starting with # or _ are reserved | Never start an application topic with either |
Two matching details catch people. First, animals/domestic/> does not match animals/domestic itself, per the wildcard reference; > needs at least one more level. Second, * and > are literal when they appear in a published topic, and Solace recommends avoiding them there. A > after a prefix, as in line3>, is also literal, not a wildcard.
Reserved prefixes are in use. The reserved topics list includes #P2P/ for per-client inboxes, #share/ for load-balanced direct subscriptions and #noexport/ for subscriptions that should not propagate across a mesh. MQTT clients use _P2P in place of #P2P.
Solace’s recommended topic structure
Solace’s topic architecture best practices recommend Domain/Noun/Verb/Version/Properties. The root says what happened (the domain that owns it, the object, the action or state change, and a version), and the properties that follow are “ordered in terms of cardinality: from least specific to most specific”. It adds that “a property should be included only if it is useful for subscriber filtering, event routing, or access control”, and that *, >, spaces and special characters should be kept out of topics.
Unified namespace designs usually do the opposite and start with location: enterprise/site/area/line/cell/..., mirroring the ISA-95 equipment hierarchy described in ISA-95. Both orders work on Solace, for one reason: if every topic of a given type has the same depth, * can stand in for any level, including the event type. The worked tree below puts the event type first, as Solace advises, and keeps location levels fixed so that location-first questions are still one subscription away.
A worked ISA-95 topic tree for a plant
An illustrative design for a fictional manufacturer with sites in Montreal (mtl) and Chicago (chi). The pattern is:
mfg/{noun}/{verb}/v1/{site}/{area}/{line}/{cell}
What each level is for. mfg is the domain (the manufacturing systems, owned by one team). machine/stateChanged is the noun and verb. v1 lets a payload change ship as v2 alongside the old one while consumers migrate. Then site, area, line and cell, from least to most specific, exactly as ISA-95 nests them. Other event types follow the same shape, for example mfg/batch/completed/v1/mtl/process/kettle2/- and mfg/quality/sampleRecorded/v1/chi/packaging/line1/checkweigher.
Keep the depth fixed. The kettle2/- above is deliberate: a process unit with no cell still publishes a placeholder at the cell level, so * positions mean the same thing in every topic. This one rule is what makes the third subscription in the diagram work.
Good and bad topics
| Topic | Verdict | Why |
|---|---|---|
mfg/machine/stateChanged/v1/mtl/packaging/line3/filler | Good | Typed, versioned, fixed depth, least to most specific |
mfg/order/released/v1/mtl/packaging/line3/- | Good | Same shape for a non-machine event; placeholder keeps depth |
Montreal Plant/Line 3/Filler Temp | Bad | Spaces, mixed case, no type or version; consumers will mistype it |
mfg/machine/stateChanged/v1/mtl/line3/filler | Bad | Missing the area level, so * positions shift and patterns silently miss it |
mfg/machine/temperature/v1/mtl/packaging/line3/filler/72.4 | Bad | A value in the topic; that belongs in the payload |
plc12/N7_40 | Bad | Names a memory address, not the equipment; meaningless to the business |
/mfg/machine/stateChanged/v1/... | Bad | The leading slash creates an empty first level, supported mainly for MQTT compatibility |
_line3/state or #mfg/... | Bad | Reserved prefixes |
High-cardinality properties are fine when they filter. Adding an order or lot number as a final level is legitimate if a consumer will subscribe by it; Solace’s guidance only asks that every property earn its place.

MQTT clients and Sparkplug in a Solace topic hierarchy
MQTT clients share the same topic space. MQTT’s + corresponds to * and # to >, with one difference to test: in MQTT 5.0, a/# also matches a, while Solace’s a/> does not. Sparkplug B imposes its own fixed form, spBv1.0/<group_id>/<message_type>/<edge_node_id>/<device_id>, which carries no ISA-95 levels; the location usually lives in the group and node names or in a remapping layer. The trade-offs are covered on Solace and Sparkplug B and in our unified namespace guide.
How to design a Solace topic hierarchy for your plant
- List the questions consumers will ask. “Every filler”, “everything at Chicago”, “all quality events this week”. Each question should map to one subscription; if it needs ten, the order of levels is wrong.
- Fix the event types first. Agree the nouns and verbs (
machine/stateChanged,batch/completed,order/released) and a version for each, owned by a named team. - Borrow the equipment hierarchy you already have. Most plants have an ISA-95 style model in MES, the historian or the asset register. Reuse its site, area, line and cell names rather than inventing new ones, and write down the short codes.
- Set naming rules. One case convention (Solace suggests camelCase or PascalCase), no spaces, no reserved prefixes, placeholders for missing levels.
- Test the patterns before go-live. Write the subscriptions your first five consumers need and check each one against sample topics, including the edge cases: a cell-less unit, a new line, an MQTT client.
- Publish the standard and review changes. A topic tree is a shared contract, and it decays the first time someone adds a level without asking.
Where it gets hard
- Changing the tree later is expensive. Every subscription and queue mapping depends on it. Version the root and run old and new side by side rather than renaming in place.
- Ownership across sites. Two plants that each “fix” the hierarchy locally produce two hierarchies. Publish the standard, ideally in a catalogue such as Solace Event Portal, and review new topics.
- Access control follows the tree. ACLs grant publish and subscribe rights by topic pattern, so a poorly ordered tree makes least-privilege rules long and fragile. Design both together; see message VPNs and security.
- Mesh propagation. Subscriptions propagate between brokers in an event mesh, so very broad patterns such as
mfg/>at a remote site pull every message across the WAN.
Next in this section: queues and guaranteed messaging, where these subscriptions are attached to durable queues.
Frequently asked questions
What is the difference between * and > in Solace topics?
In a subscription, * matches exactly one level, and > matches one or more levels but only when it stands alone as the last level. So mfg/*/state matches mfg/line3/state but not mfg/line3/filler/state, while mfg/> matches both. When a * follows a prefix, as in line*, it matches that prefix plus any characters within the level. In published topics both characters are literal.
How long can a Solace topic be?
Solace documents a maximum of 250 bytes, excluding the null terminator, and a maximum of 128 levels. All UTF-8 characters are allowed except null, and topics are case-sensitive. Because the limit is in bytes, non-ASCII characters use more than one byte each, so long plant and equipment names can reach the limit sooner than a character count suggests.
How do MQTT wildcards map to Solace wildcards?
MQTT's single-level + corresponds to Solace's *, and MQTT's multi-level # corresponds to Solace's >. One difference matters: in MQTT, a/# also matches the parent topic a itself, while Solace's a/> needs at least one more level. If MQTT and native Solace clients share a namespace, test the parent-level case on the broker release you run.
Should a plant topic start with the location or with the event type?
Solace's own guidance puts the event type first (domain, noun, verb, version) and then properties such as location, ordered from least to most specific. Unified namespace designs usually start with the location. Either works on Solace if every topic has a fixed depth, because * can then stand in for any level, including the event type.
Can a Solace queue exclude some topics?
Yes. A queue's topic subscriptions can include exceptions written with a leading !, for example !mfg/machine/stateChanged/v1/mtl/packaging/line9/>, which stops those messages reaching the queue even though a broader subscription matches them. Exceptions apply to queue subscriptions, which makes them useful for keeping a commissioning line or a test cell out of production consumers.
References and further reading
- Solace Message Format (SMF) Topics · SolaceThe structural rules: 250 bytes, 128 levels, case sensitivity, exceptions.
- Wildcard Characters in Topic Subscriptions · SolaceExact matching rules for * and >, with examples.
- Topic Architecture Best Practices · SolaceSolace's recommended domain/noun/verb/version/properties structure.
- Reserved Topics · Solace
- ISA-95 Standard: Enterprise-Control System Integration · ISAThe equipment hierarchy the worked example borrows from.
- MQTT Version 5.0 · OASISFor the + and # wildcard semantics MQTT clients expect.