Skip to content

What's your UNS maturity level? Get a custom report: Take the UNS Maturity Assessment

Building a Unified Namespace: Why MQTT Outperforms NATS

by Jens Deters
15 min read

Is NATS Ideal for Building a UNS?

NATS is an open-source messaging system that uses a lightweight publish/subscribe model to exchange data among distributed applications. It stands out for its high performance and simplicity, making it ideal for microservices and real-time processing, particularly when low latency is a priority. 

Under the hood, NATS manages message routing with a simple subject-based approach, allowing you to filter and subscribe to relevant data streams using wildcard tokens. It supports horizontal scaling with automatic clustering, letting you handle massive workloads with minimal operational overhead. 

Additionally, an extension called JetStream offers persistence and streaming capabilities, so you can replay messages or store them for durable processing without sacrificing speed. 

Because of its design roots in cloud-native environments, DevOps teams and container-focused organizations leverage NATS for rapid and efficient service-to-service communication. It doesn’t, however, include all the industrial or device-oriented features often found in MQTT ecosystems, so broader IoT or OT integration may require custom solutions. 

Even so, its straightforward configuration, flexible subscription patterns, and wide language support make it a compelling choice for modern, high-throughput applications that thrive on simplicity.

NATS Subjects: Fast, Flexible (but Flat)

In NATS, the subject is the core addressing mechanism for publish/subscribe, where:

  • Publishers send messages to a subject (similar to a MQTT topic)

  • Subscribers listen to subjects (or subject patterns with wildcards)

A subject in NATS is a string identifier used to label messages, it can be seen as a channel name, if both publisher and subscriber refer to the same subject, the message is delivered.

Example: 

Subject: 

bottleinc.berlin.filling.fillingline1.filler.temperature

NATS supports two simple wildcard types in subscriptions (not in publishing):

  • * =  matches exactly one token

  • > = matches one or more tokens

Wildcard Pattern Description
bottleinc.> Everything under “bottleinc”
bottleinc.*.filling.*.filler.temperature One level wildcard at site & line level
*.*.filling.fillingline1.filler.temperature Any company/site, fixed equipment path

While NATS offers a powerful and fast publish/subscribe system using dot-delimited subjects, its flat subject model lacks the native true hierarchical structure that MQTT provides, since subjects are not:

  • Hierarchical (the broker doesn’t interpret structure like MQTT)

  • Queues (messages go to all matching subscribers unless using queue groups)

  • Retained (no message persistence unless JetStream is enabled)

In a Unified Namespace, where the topic tree is used to represent the structure of an entire organization - from enterprise to site, area, line, and cell/asset - this hierarchy is essential. MQTT's topic syntax bottleinc/berlin/filling/fillingline1/filler/temperature aligns naturally with this model, allowing for dynamic topic creation, granular filtering, and intuitive organization of data streams. 

In MQTT this implies a clear hierarchy:

NATS Subjects: Fast, Flexible (but Flat)Wildcards like + and # enable flexible subscription patterns across deeply nested levels, making MQTT far better suited for representing complex industrial systems. 

While NATS can simulate this behavior using naming conventions and flat subjects, MQTT remains the stronger choice when modeling a stateful, hierarchical, and easily navigable namespace across OT and IT systems.

Key Differences in topics at a Glance

Feature MQTT Topics NATS Subjects
Separator Slash /Dot .
Hierarchy awareness ✅ Yes – broker interprets levels❌ No – flat structure
Wildcards + (one level), # (multi-level)* (one token), > (one or more tokens)
Enforced topic structure ✅ Yes (path-like)❌ No – just naming convention
Semantic topic navigation ✅ Natural🟡 Simulated via naming
Used for structured UNS? ✅ Ideal🟡 Somehow possible, but needs a lot of discipline

Is NATS Stateful Like MQTT?

What Does “Stateful” Mean Here?

In messaging, stateful often refers to things like:

  • Retained messages (holding last-known values)

  • Offline message delivery (store-and-forward)

  • Tracking delivery status (QoS)

  • Session awareness

MQTT is stateful by design, it holds the “current state” of the system. This design is perfect for UNS modeling where clients need to know the latest status of things (e.g., machine state, line status).

NATS Core is not stateful like MQTT, NATS JetStream can partially mimic MQTT’s stateful behavior, but it's different under the hood.

NATS Core = Stateless

When you're using plain NATS:

  • Messages are fire-and-forget

  • No storage, no tracking, no memory of past messages

  • Subscribers must be online and connected to receive messages

If a subscriber is disconnected the message is gone. No retries, no buffering.

-> It’s like a stateless API — no history, no baggage.

NATS JetStream = Stateful

JetStream adds state to enable:

  • Persistence (store messages to disk or memory)

  • Durable consumers (track what a subscriber has seen)

  • Acknowledgments (to ensure delivery)

  • Stream offsets, delivery retries, replay

  • So now, NATS remembers what was sent, who consumed what, and what needs to be retried or held.

-> It’s now like a message queue or event store - full stateful delivery logic.

NATS & Quality of Service

NATS Core (without JetStream):

  • Messages are delivered at most once (fire-and-forget)

  • No persistence, no acknowledgment

  • If a subscriber is offline, messages are lost

-> Fast and lightweight — but no delivery guarantees. MQTT is better if you need protocol-level delivery guarantees, especially in OT environments.

NATS JetStream (persistence layer):

  • Adds at-least-once delivery: Adds at-least-once delivery by storing messages in streams and requiring subscribers to acknowledge them; if a message isn't acknowledged, it is redelivered.

  • No built-in "exactly once" delivery (like MQTT QoS 2), but deduplication is possible with custom logic.

-> Similar to MQTT QoS 1, but the user controls behavior with consumers.

NATS & Retained Messages

With MQTT, retained messages act like a built-in key-value store - each topic holds the current state. With JetStream, a log of events is managed, not just the current state - more like Kafka than MQTT.

So if you want to model a current state view of your shopfloor like a UNS does, you need to:

  • Set up streams per asset/topic pattern

  • Create durable consumers

  • Implement logic to always read the latest message

  • Optionally simulate a "retained message" behavior

NATS on the Edge

Is NATS Edge Device Friendly? Yes, but again with conditions:

NATS Core on Edge

NATS Core is a good fit for edge devices because it’s lightweight, fast, and easy to deploy. It runs as a single static binary (around 5–10 MB), requires very little CPU and memory, and operates with zero external dependencies. It's fast, asynchronous publish-subscribe model makes it ideal for real-time edge scenarios.

Thanks to its minimal footprint, NATS Core can easily run on a wide range of edge platforms, including Raspberry Pi, industrial edge gateways, small Docker containers, and Linux-based single-board computers (SBCs).

However, it’s important to understand the trade-offs. 

While NATS Core shines in performance and simplicity, it’s important to understand its limitations, as Core is stateless:

No message buffering if the subscriber is offline

No delivery retry or durability guarantees

No retained messages like in MQTT

In other words: if a message is sent and the listener isn’t there, the message is gone.

NATS JetStream on Edge: Be Careful

NATS JetStream brings durability and delivery guarantees, but it comes with added resource demands.

Running JetStream on constrained edge devices is generally not recommended. It requires disk space or significant RAM to store message streams and manage consumer state, delivery acknowledgments, and stream compaction. Under load, it can consume several hundred megabytes of memory.

NATS JetStream is much better suited for more powerful hardware like edge servers, cloud instances, or industrial gateways equipped with SSDs and sufficient CPU capacity.

Key Reasons Why NATS is Not an Ideal Protocol for a UNS:

  • Hierarchical topic model: Flat subjects make modeling assets like factory/line1/machineA/temperature harder than MQTT's native hierarchy

  • Standard protocol: MQTT is standardized (ISO/IEC 20922), NATS is not -  making it less interoperable for 3rd-party OT tools

  • Lack of ecosystem support in OT world: Most industrial protocols and vendors (e.g., Siemens, Rockwell, Ignition, Kepware) support MQTT, often with Sparkplug B. NATS has almost zero native support in OT/SCADA tooling, A UNS needs to connect OT, IT, and cloud - MQTT already sits at that intersection.

  • QoS levels for delivery: MQTT has standardized QoS 0/1/2; NATS core is fire-and-forget, JetStream adds at-least-once delivery and stream replay, but it still works differently from MQTT QoS.

  • Retained messages: MQTT’s retained messages are core to UNS behavior; in NATS, you’d need to emulate it using JetStream (extra effort, e.g. to implement a instant retained message delivery to clients)

  • Edge support: NATS Core lacks support of UNS critical features, while NATS JetStream is too heavy for constrained devices, it is unsuitable for MCUs, PLCs, or simple edge devices - where a UNS should ideally begin.

Conclusion

If you're building a UNS that spans shopfloor to cloud, and especially if you're working with OT systems, then MQTT is the clear winner. If you're building a real-time event backbone across cloud-native microservices as part of the UNS, NATS can shine, especially with JetStream.

You can even combine them to get the best of both worlds. In some enterprise-scale UNS designs, MQTT is used at the edge, and NATS powers high-speed processing and integrations in the cloud.

Jens Deters

Jens Deters is the Principal Consultant, Office of the CTO at HiveMQ. He has held various roles in IT and telecommunications over the past 22 years: software developer, IT trainer, project manager, product manager, consultant, and branch manager. As a long-time expert in MQTT and IIoT and developer of the popular GUI tool MQTT.fx, he and his team support HiveMQ customers every day in implementing the world's most exciting (I)IoT UseCases at leading brands and enterprises.

  • Contact Jens Deters via e-mail
HiveMQ logo
Review HiveMQ on G2