Skip to content
MaestroHub
Menu
Partner portalFree trialGet started

CTO Notes

The Fifth Bridge: Why Your Namespace Should Leave Through One Pipeline

Four teams want plant data on four brokers. The usual answer is four bridges, and every new consumer adds another. The better answer is to decide once what leaves the namespace, and let every destination receive it in its own language.

A Question That Sounds Like Plumbing

A partner asked me last week how hard it would be to get their unified namespace into Kafka, NATS, MQTT and RabbitMQ. It sounded like a plumbing question. It is an architecture question.

Their plant data already lives in one namespace, organised the way the plant is: site, area, line, machine, signal. Now four teams want it. The data platform team runs Kafka. A new application team chose NATS. The edge and SCADA side speaks MQTT. An older integration layer listens on RabbitMQ.

Nobody in that room was asking for anything unusual. Every plant that gets its data into one place soon finds that everyone wants a copy, and each of them wants it on the system they already run. The question is never whether the data leaves the namespace. It is how many ways it leaves.

A BRIDGE PER CONSUMER UNS bridge 1own formatKafka bridge 2own formatNATS bridge 3own formatMQTT bridge 4own formatRabbitMQ bridge 5new formatteam 5 ONE EXIT UNS Pipeline1 subscription1 messageoutputs, oneper destination Kafka NATS MQTT RabbitMQ team 5
Figure 1Two ways out of the namespace. On the left, every consumer gets its own bridge, and the fifth team gets a fifth one. On the right, the decision about what leaves is made once, and a new team is one more output.

The answer most people have in mind is the left half of that picture. I want to explain why I think it gets more expensive every time you use it, and what we did instead.


How Bridges Multiply

The first bridge is easy. The trouble starts with the third, and it is never a single failure. It is drift.

A bridge is a small, reasonable thing: subscribe to the namespace, reformat, publish somewhere else. So each team gets one. Each bridge has its own subscription, its own idea of what a message looks like, and its own way of failing.

Six months later, a familiar picture appears. I am describing a composite here, not one plant, but every part of it is something I have seen. One bridge sends timestamps in local time and another in UTC. One drops the quality flag because nobody asked for it at the time. One was written to subscribe to Line 2 and quietly misses the new Line 4. When a consumer reports a missing value, three people look in three places, because there is no single place that knows what should have left.

None of these bridges is wrong on its own. The problem is that the decision about what leaves the namespace and in what shape has been made four times, by four people, at four different moments. And the fifth team that asks for data does not get the benefit of the first four. It gets a fifth bridge.


What a Bridge Cannot Know

A bridge copies messages. A namespace knows things about them.

When a value is published into a unified namespace, it carries more than a number. It has a place in the plant’s structure. It has the time it was measured, which is not always the time it arrived. It has a quality: good, uncertain or bad, with a reason.

A VALUE IN THE NAMESPACE PLACE trabzon filling-hall line-2 p101 flow VALUE27.19 MEASURED10:04:00.000Zevent time ARRIVED10:04:00.180Znot always the same QUALITYgoodor uncertain, bad + why SOURCEthe connection that read it WHAT A BRIDGE SEES TOPICplant/line-2/p101/flow PAYLOAD27.19 measured when?unknown trustworthy?unknown which machine?parse a string
Figure 2The same value, twice. The namespace knows where the value sits in the plant, when it was measured and whether to trust it. A broker-to-broker bridge sees a topic string and a payload, and keeps only what someone remembered to put in the payload.

A bridge that copies from one broker to another sees a payload and a topic string. If the quality was not in the payload, it is gone. If the timestamp in the payload is the arrival time, the measurement time is gone too. Every bridge has to rediscover, or quietly lose, what the namespace already knew.

Key idea

The real cost of a bridge is not its code. It is that each copy is a little poorer than the source, and poorer in its own way.


Decide Once, Deliver Many

The design I prefer separates two questions that bridges mix together: what leaves, and where it goes.

In MaestroHub we built the partner’s case as one pipeline. It does three things.

First, it subscribes to a part of the namespace. That is one pattern: one line, one hall, every product temperature in the plant, or all of it. Changing what leaves is an edit to that pattern, in one place.

Second, it decides what a message looks like, once. The value, the topic it came from, the time it was measured, its quality. Every destination receives that same message. If tomorrow every consumer needs the site name as well, it is added once and arrives everywhere.

Third, it hands the message to each destination in that destination’s own language. This is where four brokers stop looking like four problems. Each has its own naming conventions, and all of them can be derived from the same namespace path.

ONE NAMESPACE PATH trabzon filling-hall line-2 p101 flow site / area / line / machine / signal Kafkatopic plant-data, keytrabzon/filling-hall/line-2/p101/flow NATSsubjectplant.trabzon.filling-hall.line-2.p101.flow MQTTtopicmqtt/plant/trabzon/filling-hall/line-2/p101/flow RabbitMQrouting keytrabzon.filling-hall.line-2.p101.flow A RabbitMQ queue bound withtrabzon.filling-hall.*.*.vibration receives...line-2.p101.vibrationskips...line-2.p101.flowno filter in the pipeline
Figure 3One path, four dialects. Kafka keys by signal, so each signal keeps its order within its partition. NATS and RabbitMQ use dots, so their consumers can filter with their own wildcards. These are the real names from our test on a simulated bottling plant.

The consequence I like most is downstream. Because NATS and RabbitMQ received dotted names, their consumers could use their own wildcards. A RabbitMQ queue that only wanted pump vibrations bound to a pattern and received exactly that, while the pipeline did no filtering at all.

It helps to know that the four brokers do not share a wildcard language, which is one more reason to derive each name from the path rather than hand-write it per bridge:

Broker Separator One level Everything below
MQTT / + #
NATS . * >
RabbitMQ (topic exchange) . * #
Kafka none: a topic is a name, the key picks the partition

One small surprise along the way. The MQTT destination was not a separate broker at all. NATS has an MQTT listener built into the server, so one NATS server served both NATS and MQTT clients, and NATS consumers could read the MQTT messages directly as subjects. Many plants already run more brokers than they need.


The Day One Broker Goes Down

Bridges are usually judged on the day they work. I would rather judge them on the day something breaks.

So we broke something. With the plant publishing continuously, we stopped RabbitMQ for 47 seconds, then started it again.

DESTINATIONS Kafka NATS MQTT RabbitMQdown for 47 s RABBITMQBUFFERON DISK replayed when it returns buffer empty again 0 sstopstart2 min 1,041 values stamped inside the outage reached RabbitMQ afterwards. Largest gap: 1 s, the plant's own interval.
Figure 4What we measured. The other three destinations never noticed. RabbitMQ's messages waited in its own buffer on disk and were delivered, with the time each value was produced, once it came back. We ran it twice with the same result.

Kafka, NATS and MQTT did not notice, because in MaestroHub each destination in the pipeline keeps its own buffer on disk. While RabbitMQ was away, only RabbitMQ’s messages waited. When it came back, they were delivered with the time each value was produced. Nothing was lost.

There is one design choice hiding in that story, and I think it deserves to be a choice rather than a default nobody looked at: what should happen to order when a destination refuses a message?

HANDED TO THE BUFFERWHAT THE DESTINATION RECEIVES Any orderreadings 123456 124563 3 retries behind the newer ones; nothing waits In ordercommands, setpoints 123456 123456 4, 5 and 6 wait until a person retries 3,skips it, or moves it aside
Figure 5The same refused message, two policies. For readings, each value carries its own time, so letting newer ones pass costs nothing. For a command, an older instruction must never land after a newer one, so everything waits for a decision.

MaestroHub makes this a setting on each destination. Kafka’s connector asks for strict order by default; the other three default to keep going. The point is not which default is right. The point is that with one pipeline, the choice is made deliberately, per destination, in a place you can see.


Day Two Is the Real Test

Any design looks fine on the first request. What matters is what the fifth one costs.

BRIDGE PER CONSUMERONE PIPELINE Subscriptions to the namespace Definitions of the message Places to look when a value is missing What the fifth team costs a new bridge, written againone more output
Figure 6What changes when the fifth team arrives. With bridges, every count grows with the number of consumers. With one exit, they stay at one, and the new team costs a single output on a message that already exists.

With one pipeline, the fifth team is a fifth output on the same message. It does not have to be a broker; MaestroHub 3.0 has 111 connectors, and a time-series database or a cloud event hub fits in the same place. The subscription and the message definition stay as they are.

Moving a broker from a test machine to production is a change to its connection, not to the flow. Removing a consumer removes one output; the others keep running. And when something does go wrong, there is one place to look. Every run of the pipeline is recorded with what each destination returned, and every failure is kept with its reason. A team that asks did my value leave? gets an answer from the same place as every other team.

Key idea

Give the namespace one exit, designed on purpose. Then every destination is a view of the data rather than a copy of it, and adding a consumer means adding a destination, not another opinion about the data.


Five Questions Before You Build the Next Bridge

If your plant already has a few bridges, these questions tell you how much the next one will really cost.

  1. Does every consumer receive the time a value was measured, or the time it was forwarded?
  2. Which consumers receive the quality of a value, and which silently get a bare number?
  3. When a machine is added to the plant, how many subscriptions have to change for every consumer to see it?
  4. When one destination is down for an hour, what do the others lose, and what does it lose?
  5. If a consumer says a value never arrived, where do you look first, and is it the same place for every consumer?

If the honest answers differ from bridge to bridge, the bridges have already drifted.


Where This Stands, Honestly

Everything described here is in the 5 November 2026 release: the namespace trigger, the pipeline, the Kafka, NATS, MQTT and RabbitMQ connectors, per-destination buffering with a delivery order setting, and the run history.

What our test was, and was not. It ran on one machine, with one node per broker, no TLS and short retention. Production brokers need their own sizing, replication and security, and every connector used here supports TLS and authentication. The data came from our demo plant, a simulated bottling plant built for demos and training, not production.


The Question I Want to Leave You With

How many places in your plant decide what a message looks like?

If the honest answer is one per consumer, every new team that wants plant data costs you another bridge, another format, and another thing to watch at three in the morning. I would rather a namespace had one exit, designed on purpose.

We packaged the setup from this article as a small Docker demo that runs on a laptop in a few minutes, with the plant, the four brokers and the pipeline already built. If you would like to try it, or to try the same pattern against your own brokers, get in touch.

Rather see it on your own plant?

Tell us what systems you run and what you're trying to achieve. Our team can help you explore the right licensing and implementation options.

Cookie preferences

Choose which categories of cookies you allow. Strictly necessary cookies are always on because the site cannot function without them.