Sensors Edge Hub Logo
What Is Sparkplug B? MQTT That Plant Systems Can Trust

What Is Sparkplug B? MQTT That Plant Systems Can Trust

Plain MQTT cannot tell you whether a sensor is alive or just quiet. A transmitter that lost power keeps looking "connected" in most dashboards until a shift supervisor notices the reading never changed. That silent failure is the gap Sparkplug B was built to close, and it's why almost every serious industrial MQTT rollout adopts it instead of inventing its own conventions.

Teams pick up MQTT for its light footprint, then hit the same three walls a few months in: topic names nobody agreed on, payloads nobody can verify the meaning of, and no way to know if a device is really there. Sparkplug B answers all three with one open specification. This piece skips the OPC UA vs MQTT layer question, covered separately along with what OPC UA actually is, and goes straight into how Sparkplug B works under the hood.

TL;DR: Sparkplug B is an open Eclipse specification layered on standard MQTT (v3.0 became the first official Eclipse spec in 2022). It fixes what raw MQTT lacks for industry: a standard topic namespace (spBv1.0/group/type/node/device), stateful birth and death certificates that make device liveness knowable in real time (death delivered via MQTT's Last Will and Testament), and self-describing protobuf payloads 60-75% smaller than JSON. Combined with metric aliases and report-by-exception, it cuts bandwidth 80-95% versus polling.

An Art Deco illustration of tangled cable runs resolving into an ordered grid, representing how Sparkplug B adds structure to raw MQTT traffic

What Is Sparkplug B, and Why Does Plain MQTT Need It?

Sparkplug B is an open Eclipse specification that defines how to use MQTT for industrial data. Raw MQTT is a bare transport; it defines no topic structure, no payload meaning, and no device state, so every team that adopts it ends up solving the same three problems on its own.

MQTT itself is OASIS-standardized and has been stable for years across versions 3.1.1 and 5. Sparkplug B is a separate layer on top of it, and its history is short by comparison. Eclipse Sparkplug v3.0, released in 2022, was the first version to become an official Eclipse Foundation specification rather than a community convention (Eclipse Foundation, i-FLOW, 2022).

Without that layer, plain MQTT leaves three gaps open. First, topic chaos: one engineer writes plant1/line4/temp, another writes Line4_Temp_Sensor, and a multi-vendor site ends up with as many topic conventions as it has integrators. Second, payload ambiguity: a bare number like 72 could be Celsius or Fahrenheit, and nothing in the message says which. Third, statelessness: MQTT's transport layer has no concept of "this device is currently online," so a subscriber has no reliable way to tell a dead sensor from a quiet one.

Citation capsule: Sparkplug B is an Eclipse Foundation specification that standardizes how MQTT gets used for industrial telemetry, rather than replacing MQTT itself. Version 3.0, released in 2022, became the first official Eclipse spec (Eclipse Foundation, i-FLOW). It exists to close three gaps in bare MQTT: undefined topic structure, ambiguous payload meaning, and no built-in awareness of whether a device is actually online.

Sparkplug B never touches the broker itself. It's a usage convention, a set of rules for what goes in the topic string and the payload, riding on infrastructure you already have.

What Does the Sparkplug B Topic Namespace Look Like?

Every Sparkplug B message follows one fixed structure: spBv1.0/group_id/message_type/edge_node_id/[device_id]. Instead of every team inventing its own topic scheme, a Sparkplug-aware subscriber can parse any compliant publisher's topics on sight, with no vendor-specific mapping layer required.

Each segment carries a specific job. The spBv1.0 prefix marks the version and encoding so nothing downstream mistakes it for plain MQTT. The group ID bundles edge nodes logically, typically by plant, site, or functional unit. That's why ExampleCompany:Prague and ExampleCompany:Berlin never collide on the same broker (i-FLOW). The message type slot carries one of the defined message types: NBIRTH, DBIRTH, NDATA, DDATA, NDEATH, DDEATH, NCMD, DCMD, or STATE (i-FLOW, FlowFuse). Edge node ID and device ID close out the path, identifying the specific gateway and, when present, the specific device attached to it.

spBv1.0 namespace group_id (plant / site) message_type NBIRTH, NDATA... edge_node_id gateway node [device_id] (optional) Example: spBv1.0/PlantA/NDATA/Line3/Sensor7 Source: i-FLOW, FlowFuse
The fixed Sparkplug B topic structure: namespace, group, message type, edge node, and an optional device segment.

A worked example makes the rigidity concrete: spBv1.0/ExampleCompany:Prague/DDATA/MillingArea1:Line1/Cell1 tells you, without opening an integration document, that this is telemetry from a specific cell, line, and site. Onboarding a new production line gets faster because everyone touching the broker already speaks the same topic language, so nobody negotiates a scheme from scratch.

What Are Birth and Death Certificates?

A birth certificate, NBIRTH for a node or DBIRTH for a device, is a full self-introduction published the moment something connects to the broker. It lists every metric the device exposes, along with datatypes, aliases, and initial values, so any consumer instantly knows what exists and what state it's in.

A death certificate, NDEATH or DDEATH, is the mirror image: it announces that a node or device is gone. That distinction, a device confirmed gone rather than merely inferred from a stale value, is the single feature that most convinces controls teams MQTT belongs on a real plant floor.

A film-noir control room with an annunciator status board, one lamp lit and an adjacent one gone dark, capturing the instant Sparkplug B marks a device's birth or death

Most write-ups skip past one detail. On a clean, expected disconnect, the device can publish its own death certificate. But on an unexpected failure, power loss, cable pull, network drop, there's no device left to publish anything. That's where MQTT's own Last Will and Testament mechanism does the work. A device registers its death certificate as a Last Will at connect time. The broker itself auto-publishes it the moment it detects the connection is gone, whether through a TCP failure or a missed keep-alive (FlowFuse, i-FLOW). Sparkplug defines what the death certificate means; MQTT's broker guarantees it gets delivered.

NBIRTH announce state + metrics + aliases online: NDATA values by alias, report-by-exception NDEATH via MQTT Last Will & Testament offline broker auto-publishes on unexpected drop LWT makes liveness real-time: the broker detects a dropped connection and delivers the death certificate itself Source: FlowFuse, i-FLOW
The Sparkplug B device lifecycle, from birth certificate to broker-delivered death certificate via MQTT's Last Will and Testament.

Citation capsule: A Sparkplug B death certificate announces a device leaving the network, but on unexpected failures there is no device left to send one. The specification solves this by registering the death certificate as an MQTT Last Will and Testament at connect time. The broker itself then detects the dropped connection and auto-publishes the death message on the device's behalf (FlowFuse, i-FLOW). That handoff, from application-layer intent to broker-guaranteed delivery, is what makes device liveness real-time and trustworthy instead of a guess based on stale data.

That LWT handoff is why Sparkplug B feels different from a home-rolled "heartbeat topic" convention. A heartbeat tells you a device was alive as of its last publish. A death certificate tells you the moment it stopped, delivered by infrastructure that was watching the connection the whole time.

How Does Sparkplug B Cut Bandwidth So Much?

Three mechanisms stack on top of each other. Protocol Buffers replace JSON and run 60-75% smaller on the wire. Metric aliases replace long metric names with short numeric IDs after the first message. Report-by-exception means devices only publish when a value actually changes. Combined, the numbers add up to 80-95% less bandwidth than a polling architecture (i-FLOW, Corso, FlowFuse, 2026).

Protocol Buffers vs JSON

Protobuf does the first layer of work. Rather than the repetitive field names and punctuation JSON requires on every message, Sparkplug B encodes payloads in Google's binary Protocol Buffer format across 19 formally defined datatypes, dropping payload size 60-75% compared to the equivalent JSON (i-FLOW, Corso). The first time I compared a raw JSON payload against its Sparkplug equivalent side by side, the size difference alone explained why cellular and satellite-linked remote sites lean on this spec heavily.

Metric aliases

Metric aliases stack on top of that. Industrial metric names easily run 30 to 100 characters, something like MillingArea1.Line1.Cell1.SupplyVoltage. The birth message sends that full name once, alongside a short numeric alias; every subsequent NDATA or DDATA message sends only the numeric alias, which can cut effective payload size up to 80% (i-FLOW). Alias resolution happens entirely on the consumer side, based on the birth message it already received, which is why Sparkplug enforces strict birth-before-data ordering.

Report by exception

Report-by-exception is the third layer: instead of polling every tag on a fixed interval, a device publishes only when a value changes. Stack all three mechanisms together and the FlowFuse figure is 80-95% less bandwidth than a comparable polling setup (FlowFuse, 2026), which matters most on constrained links like cellular or LPWAN backhaul from a remote site.

Three Stacked Mechanisms Behind the Bandwidth Cut Protobuf vs JSON payload size (% reduction, 0-100 scale) 0% 100% 60-75% Metric aliases: effective payload reduction (0-100 scale) 0% 100% up to 80% Report-by-exception + aliases + batching vs polling (0-100 scale) 0% 100% 80-95% Source: i-FLOW, Corso Systems, FlowFuse
Each mechanism is measured on its own reduction scale versus its baseline (JSON, unaliased metrics, or polling), not a shared cumulative axis.

Citation capsule: Sparkplug B's bandwidth savings come from three stacked mechanisms rather than one trick. Protocol Buffer encoding cuts payload size 60-75% versus equivalent JSON (i-FLOW, Corso); metric aliases then reduce effective payload size up to 80% by sending numeric IDs instead of long names after the birth message (i-FLOW); and report-by-exception publishing, combined with the first two, brings total bandwidth down 80-95% compared to polling architectures (FlowFuse, 2026).

None of that efficiency would hold up without a way to catch dropped messages, since QoS 0 offers no delivery guarantee. Sparkplug B handles that with two counters: seq, an 8-bit sequence number from 0 to 255 that increments on every operational message and resets on a new birth, and bdSeq, a 64-bit birth/death sequence number that increments once per session (i-FLOW). If a consumer sees a gap in seq, it knows a message was dropped and can force a REBIRTH to resynchronize. If a delayed death certificate from an old session arrives late, bdSeq stops it from wrongly killing the current, healthy one. I've traced more than one phantom "device offline" alarm back to exactly this scenario, a stale death certificate wandering in late while bdSeq quietly kept it from taking down a session that was actually fine.

How Is Sparkplug B Different from Plain MQTT?

Same broker, same publish-subscribe model, but Sparkplug B adds structure, state, and self-description that plain MQTT leaves to whoever implements it. A plain MQTT deployment can technically do everything Sparkplug does; it just has to build all of it by hand, per project, per team.

Aspect Plain MQTT Sparkplug B
Topic structure Freeform - every team invents its own Standardized spBv1.0 namespace
Payload format Anything, often ad hoc JSON Self-describing protobuf with defined datatypes
Device state awareness None - stateless, no built-in liveness Birth and death certificates track state
Discovery Custom, per-project mapping layer Self-introduction via the birth certificate
Human-readable on the wire Yes No - requires a Sparkplug-aware decoder
Per-metric subscribe Yes, subscribe to individual topics No - consumes the whole node/device payload

Sparkplug B trades plain MQTT's flexibility for a fixed structure that any compliant subscriber can already read.

Line them up side by side and the differences aren't subtle. Topic structure is whatever each team invents in plain MQTT; Sparkplug fixes it by spec. A plain MQTT payload is opaque bytes with no defined metrics or datatypes, where Sparkplug's protobuf carries both. Plain MQTT has no built-in state awareness, so Sparkplug adds birth and death certificates backed by MQTT's own Last Will mechanism. And where plain MQTT gives you no way to discover what a device offers, Sparkplug's birth message is that discovery, out of the box.

Where plain MQTT still wins is exactly where Sparkplug's structure becomes a constraint, and that's worth being honest about before recommending it everywhere.

What Does Sparkplug B Cost You?

Efficiency and structure cost debuggability and flexibility. Protobuf payloads aren't human-readable on the wire, and you can't subscribe to a single metric buried inside one. Both trade-offs surface the moment something goes wrong in production and someone needs to look at raw traffic.

Most write-ups sell Sparkplug B as a pure upgrade and skip this part. A plain-text MQTT payload can be read in an MQTT Explorer window with your own eyes. A Sparkplug protobuf payload needs a decoder that understands the schema, and without that tooling, you're staring at binary. I've been the engineer squinting at that binary at 2 a.m. during an outage, waiting on someone to remember which repo held the schema file. That's a real cost during an incident, not a theoretical one.

The per-metric subscription gap compounds it. Because a device's entire metric set ships in one payload, a consumer that only cares about one temperature reading still receives the whole blob and has to filter client-side. Plain MQTT, by contrast, lets you design topics narrow enough to subscribe to exactly one value if you want to.

Sparkplug B's Primary Host Application model adds another constraint: it's n:1 by design, meaning the spec expects one authoritative host tracking state for a given namespace. That's fine for a single SCADA system watching a plant, but it can bottleneck architectures that want many consumers treating the same data as equally authoritative. Sparkplug B also mandates QoS 0, fire-and-forget, for every operational message type: NBIRTH, DBIRTH, NDATA, DDATA, NDEATH, and DDEATH. Only the Primary Host's STATE message runs at QoS 1, because that's the one message the spec insists must arrive (i-FLOW).

When Should You Use Sparkplug B?

Use Sparkplug B where device state and structure matter: edge data collection from many devices, security-relevant remote operations, cloud or Industry 4.0 integration, and any multi-site or multi-vendor deployment where discovering what a device offers matters more than raw wire simplicity.

The guidance that gets skipped most often: treat Sparkplug B as an on-ramp, not a destination. A common pattern in mature Unified Namespace architectures is running Sparkplug B at the edge, where its structure and birth/death discipline earn their keep, then "breaking apart" the protobuf payloads back into plain, retained MQTT messages at the UNS layer (Corso Systems, i-FLOW). That's because a flexible n:m Unified Namespace treats the broker as a shared source of truth for many producers and many consumers alike. That model fights Sparkplug's rigid n:1 Primary Host design and its non-retained protobuf blobs.

Sparkplug B is not the answer for deterministic real-time machine control. That job stays on fieldbus or real-time industrial Ethernet, where millisecond-scale determinism matters more than bandwidth efficiency. Our piece on how the two protocols split the stack covers that distinction in more depth. It's also not a replacement for legacy Modbus polling on a device that has no MQTT stack to begin with, or for digital data over legacy wiring on instruments still running 4-20mA loops. It's for the edge-to-cloud telemetry layer, once you already have MQTT in the picture.

Industrial Ethernet still carries the overwhelming majority of new industrial networking nodes. MQTT and Sparkplug B have no significant market share of their own yet by comparison (FlowFuse, HMS Networks, 2025/26). That figure confirms where in the stack Sparkplug B operates: it isn't competing with fieldbus or industrial Ethernet for the same job.

Citation capsule: Best-practice Unified Namespace architectures use Sparkplug B at the edge, where its topic structure and birth/death discipline earn their value, then break the protobuf payloads apart into plain, retained MQTT messages at the UNS layer (Corso Systems, i-FLOW). Sparkplug's rigid n:1 Primary Host model and non-retained payloads work well for structured edge collection but fight a flexible n:m Unified Namespace, which is why Sparkplug B functions as an on-ramp into a UNS rather than the UNS itself.

Frequently Asked Questions

How does Sparkplug B differ from plain MQTT? They share the same broker and pub-sub model. Sparkplug B adds three things plain MQTT leaves undefined: a fixed topic namespace, birth and death certificates for device state, and self-describing protobuf payloads. Plain MQTT moves bytes; Sparkplug B moves bytes with structure and state attached.

What is the Sparkplug B topic namespace structure? Every Sparkplug B topic follows spBv1.0/group_id/message_type/edge_node_id/[device_id] (Eclipse Sparkplug spec, i-FLOW). The group ID bundles nodes by plant or site, the message type marks purpose, and the node and device IDs identify the source. Any compliant subscriber can parse it without custom mapping.

What are birth and death certificates in Sparkplug B? A birth certificate (NBIRTH/DBIRTH) is a full self-introduction a device sends on connect, listing every metric, datatype, and alias. A death certificate (NDEATH/DDEATH) announces it disconnected. Unexpected deaths are delivered by MQTT Last Will and Testament, so the broker itself reports the loss (FlowFuse, i-FLOW).

How much bandwidth does Sparkplug B save compared to JSON MQTT? Protobuf payloads run 60-75% smaller than equivalent JSON (i-FLOW, Corso). Metric aliases cut effective payload size up to 80% by replacing long names with numeric IDs after the birth message. Stacked with report-by-exception, teams see 80-95% less bandwidth than polling architectures (FlowFuse, 2026).

When should I use Sparkplug B instead of plain MQTT? Use it wherever device state and structure matter: edge data collection, multi-site or multi-vendor scaling, and cloud integration. Skip it for deterministic real-time control, which belongs on industrial Ethernet, and consider breaking Sparkplug payloads back to plain MQTT at the Unified Namespace layer for flexibility.

Conclusion

Sparkplug B disciplines MQTT rather than replacing it. Three additions, a fixed namespace, birth/death state backed by Last Will and Testament, and self-describing protobuf payloads, turn a bare transport into something a plant floor can actually rely on.

  • The namespace kills topic guesswork across teams and vendors.
  • Last Will and Testament makes device liveness real, not assumed.
  • Protobuf plus aliases plus report-by-exception adds up to 80-95% less bandwidth than polling.
  • The honest trade-off is debuggability: protobuf isn't human-readable and you can't cherry-pick one metric from a payload.
  • It's an on-ramp into a Unified Namespace, not the destination itself.

For the sensor-to-cloud layer picture this article assumes, or step back to the full IIoT protocol framework for where Sparkplug B sits alongside fieldbus and industrial Ethernet choices.

Frequently Asked Questions

How does Sparkplug B differ from plain MQTT?
They share the same broker and pub-sub model. Sparkplug B adds three things plain MQTT leaves undefined: a fixed topic namespace, birth and death certificates for device state, and self-describing protobuf payloads. Plain MQTT moves bytes; Sparkplug B moves bytes with structure and state attached.
What is the Sparkplug B topic namespace structure?
Every Sparkplug B topic follows spBv1.0/group_id/message_type/edge_node_id/[device_id] (Eclipse Sparkplug spec, i-FLOW). The group ID bundles nodes by plant or site, the message type marks purpose (birth, data, command, death), and the node and device IDs identify the source. Any compliant subscriber can parse it without custom mapping.
What are birth and death certificates in Sparkplug B?
A birth certificate (NBIRTH/DBIRTH) is a full self-introduction a device sends on connect, listing every metric, datatype, and alias. A death certificate (NDEATH/DDEATH) announces it disconnected. Unexpected deaths are delivered by MQTT Last Will and Testament, so the broker itself reports the loss (FlowFuse, i-FLOW).
How much bandwidth does Sparkplug B save compared to JSON MQTT?
Protobuf payloads run 60-75% smaller than equivalent JSON (i-FLOW, Corso). Metric aliases cut effective payload size up to 80% by replacing long names with numeric IDs after the birth message. Stacked with report-by-exception, teams see 80-95% less bandwidth than polling architectures (FlowFuse, 2026).
When should I use Sparkplug B instead of plain MQTT?
Use it wherever device state and structure matter: edge data collection, multi-site or multi-vendor scaling, and cloud integration. Skip it for deterministic real-time control, which belongs on industrial Ethernet, and consider breaking Sparkplug payloads back to plain MQTT at the Unified Namespace layer for flexibility.