Product Update

Sparkplug B usually arrives on a project as a requirement rather than a preference. It is in the customer's specification, or the integrator's standard, or the tender document. Somebody decided that MQTT on its own is too loose, and they were right. Any device can publish anything, anywhere, in any format. That is exactly the flexibility that makes MQTT useful, and exactly the looseness that makes a hundred machines from forty vendors unmanageable.
Sparkplug fixes it by mandating structure. A fixed topic layout, devices that announce their own catalogue when they connect, and binary payloads instead of JSON.
Which leaves you with a second problem. You have designed a namespace that reflects your plant, in an order that makes sense to the people who work there. Sparkplug arrives with a namespace of its own, and it is not a suggestion. Now two structures both claim to be the authority on how your data is organised, and one of them cannot be read by a human with an MQTT client.
Sparkplug is maintained by the Eclipse Foundation and runs on top of ordinary MQTT. Sparkplug 3.0 is certified as an ISO/IEC international standard, which is why it appears in procurement documents rather than only in architecture discussions.
Three things it adds matter here.
A fixed topic namespace. Topics follow a defined shape: a group, a message type, an edge node, and optionally a device. Nothing is left to local convention.
State awareness through birth and death certificates. When an edge node connects it publishes a birth certificate declaring every metric it has. When it goes away, a death certificate says so. The death certificate is registered as the MQTT Will Message at connection time, so it arrives even when a device drops off the network without warning rather than shutting down politely. This is the part that earns Sparkplug its place: a consumer always knows whether the data in front of it is live or stale, which plain MQTT cannot tell you.
Binary payloads. Sparkplug uses Protocol Buffers rather than JSON. Compact, strongly typed, unambiguous to parse, and unreadable to a person looking at the topic. It also uses metric aliases, where values refer to a number declared in the birth certificate rather than repeating the name, and sequence numbers so a consumer can tell it has missed something.
Coreflux ships this as two Connectors, and the useful way to think about them is not as two features but as one question: how much authority do you want Coreflux to take in the namespace?
| Role | Connector and mode | What Coreflux does |
| Read it | SPARKPLUG_B, DECODE | Consumes the whole Sparkplug namespace arriving on the Coreflux broker and republishes it as readable JSON. Nothing outbound. |
| Join it | SPARKPLUG_B, ENCODE | Presents itself as a Sparkplug edge node, publishing births, data and deaths, and accepting commands for metrics you mark writable. |
| Both | SPARKPLUG_B, BOTH | Decodes the namespace and publishes as a gateway node. The two paths run independently. |
| Run it | SPARKPLUG_HOST | Acts as the Primary Host Application: publishes authoritative host state, decodes everything, issues commands, and repairs the namespace when nodes misbehave. |
One constraint worth knowing before you plan a deployment, because it is easy to get wrong: only one thing can consume the namespace per broker. That means one SPARKPLUG_B Connector in DECODE or BOTH mode, or one SPARKPLUG_HOST Connector, not both. Edge-node-only Connectors in ENCODE mode are unrestricted, so you can run as many of those as you have nodes to represent.
The decode path is the answer to the problem in the opening, and it is the least glamorous and most useful thing here.
Sparkplug's mandated structure stays on the wire, where the specification requires it. Coreflux republishes it as a parallel readable tree, so a metric on a device becomes a topic you can subscribe to with any client, carrying JSON with the metric's canonical name, value, datatype, timestamp and quality.
Your automations, Dashboards and storage then work off readable topics rather than opaque Protobuf. Two structures stop competing, because one is the wire format and the other is what people and logic actually read.
Alongside each metric, availability arrives as a retained status topic derived from the birth and death certificates, so an automation can check whether a node is alive without inferring it from whether values have stopped. Decode and alias-resolution failures go to their own error topic rather than disappearing into a log.
In encode mode Coreflux becomes a Sparkplug edge node in its own right, which is what you need when the host application is somebody else's and the specification says you must speak to it properly.
On connection it publishes a node birth certificate, then a device birth certificate for each device you declare, then data as source topics change. Deaths are published on a graceful stop, and delivered through the MQTT Will after a crash. A rebirth request from the host causes it to republish its births.
Metrics you mark writable accept inbound commands, and each accepted value is republished to a local topic of your choosing. So a host application changing a setpoint lands on your bus as an ordinary value the rest of your logic can see.
There is also a gating option. Point an edge node at an external Primary Host and it will watch that host's retained state, hold its births and stay quiet until the host reports itself online, then publish fresh births and resume. Worth knowing what that does not do: it does not buffer. Values produced while the host is offline are dropped rather than queued.
The Host Connector is the one that changes Coreflux's position rather than its capabilities. Here Coreflux is the Primary Host Application: the thing edge nodes are configured to look for, and the authority on whether the namespace has a listener.
It publishes retained host state, decodes the full namespace into the same readable tree as the decode path, and sends commands to nodes and devices. Commands can go through a convention topic tree with no declaration at all, using the datatype learned from the target's own birth certificate, or through explicitly declared command metrics when you want a friendly trigger topic, a pinned datatype, or the ability to command a node before it has ever announced itself.
Two details in there are worth pulling out, because they are the difference between an implementation that works on a slide and one that survives a plant.
It repairs the namespace. When a value arrives referring to an alias that was never declared, or a node's sequence number skips, Coreflux asks that node to republish its birth certificate. Rate-limited, so a genuinely unstable node does not turn into a request storm. This is the behaviour Sparkplug people use to judge whether an implementation is real.
It refuses to guess. If a command has no declared datatype and none learned from a birth certificate, Coreflux drops it rather than picking one. A dropped command you can see beats a mistyped one you cannot.
There is also protection against the classic Sparkplug failure of two hosts claiming the same identity. By default Coreflux watches for another host already asserting its Host ID and stands down for that session rather than fighting over it. You can override that when you know the other state is stale.
The series convention, and the questions you would otherwise find out in a pilot.
DataSet and Template metrics decode to JSON, so you can read them, but they cannot be published or sent as commands. Array metrics are fully supported in both directions.
Neither Connector provides durable store-and-forward replay, and Primary Host gating does not buffer. If continuity through an outage matters, that belongs in a storage or Kafka Connector, not here.
The Host Connector connects to one target broker. Multi-server Primary Host failover is not supported.
Integrators whose customers write Sparkplug B into the specification, which in North America is increasingly all of them. Anyone whose Ignition-based estate has made Sparkplug the default assumption rather than a choice. Large device and service providers who treat it as deal-critical because their own customers mandate it. And teams who have designed a namespace they actually like, and would rather not abandon it to satisfy a document. The surface is stable and the spec behaviour is what's described here. The breadth of exposure to other vendors' host applications is still being hardened.
Configuration, datatypes, command topics and the full option set are in the technical documentation. Two pages, because there are two Connectors.
👉 Sparkplug B Connector: Coreflux docs
👉 Sparkplug Host Connector: Coreflux docs