Industrial IoT

Sparkplug Metric Aliases: Saving Bandwidth in DATA Messages

Sparkplug metric aliases replace long metric names with small integers in DATA messages. This guide explains how the mapping works, when to use it, and how to debug alias mismatches.

Diagram of sparkplug metric aliases mapping long metric names in a BIRTH message to numbers in DATA messages
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

Sparkplug metric aliases let an edge node replace long metric names such as Line2/Filler/Motor/CurrentAmps with a small integer in every DATA message. In this guide you will learn how the alias mapping between BIRTH and DATA messages works, when aliases are worth the extra complexity, and how to find and fix alias mismatches when decoded values suddenly look wrong.

Why Metric Names Are Expensive

Sparkplug B payloads are Protobuf, which is already compact. Numbers are varint encoded, timestamps are 64-bit integers, and there is no JSON punctuation. The one part of a payload Protobuf cannot shrink is a string, and metric names are strings.

Industrial naming conventions make those strings long. A tag path copied from a PLC or SCADA tag browser often carries the area, the machine, the subsystem and the signal: Packaging/Line2/Filler/Infeed/Motor1/Current. When a DDATA message reports one changed value, that 45-character name can be several times larger than the value and timestamp combined.

On a wired plant network this rarely matters. On cellular links, satellite links, licensed radio or busy shared networks, it matters a great deal. Every byte is paid for, either in money or in latency. Sparkplug metric aliases are the specification's answer: send the name once, then refer to it by number.

How Sparkplug Metric Aliases Work

The mechanism has three rules.

  1. In the NBIRTH (for node-level metrics) or DBIRTH (for device metrics), each metric is sent with both its name and an alias, an unsigned 64-bit integer.
  2. In subsequent NDATA, DDATA, NCMD and DCMD messages, the metric is sent with only the alias. The name field is omitted.
  3. Aliases must be unique within the scope of an edge node. Two metrics on the same edge node, even on different devices, cannot share an alias.

A primary host application or any other consumer builds a lookup table when it receives the BIRTH. From then on, every DATA metric that arrives with an alias is resolved back to its full name through that table.

Here is the same metric in both message types, shown as the decoded Protobuf structure:

DBIRTH  spBv1.0/plant1/DBIRTH/edge-07/filler-02
  metric { name: "Infeed/Motor1/Current"  alias: 12  datatype: Float  float_value: 4.81 }
  metric { name: "Infeed/Motor1/Running"  alias: 13  datatype: Boolean  boolean_value: true }

DDATA   spBv1.0/plant1/DDATA/edge-07/filler-02
  metric { alias: 12  datatype: Float  float_value: 4.93  timestamp: 1792137600123 }

The DDATA metric carries no name at all. Without the DBIRTH, a consumer has a float and the number 12, and nothing else.

What Aliases Do Not Change

Aliases only replace the name. The datatype, value, timestamp, quality properties and metadata work exactly as before. Topics also stay the same: aliases have nothing to do with MQTT 5 topic aliases, which shorten the topic string at the protocol level. The two can coexist, but they are independent features defined by different specifications. If you want the MQTT-level version, see the topic alias section in our MQTT 5 features guide.

Names vs Aliases: Trade-offs

Aspect Names in every DATA message Sparkplug metric aliases
Payload size Grows with name length Small and roughly constant per metric
Debuggability Any captured message is self-describing DATA is meaningless without its BIRTH
Late subscribers Can decode immediately Must wait for or request a rebirth
Consumer complexity Simple Must maintain an alias table per edge node
Risk of silent errors Low A stale table maps values to the wrong metric
Best fit Wired LAN, low tag counts Metered or constrained links, high tag counts

The last row in the risk column is the one that matters. A wrong name is obvious. A wrong alias is not: the consumer happily writes a motor current into a temperature tag, and the number looks plausible.

The Alias Lifecycle in Practice

Aliases are only valid for the lifetime of a single BIRTH. Understanding when that lifetime ends prevents most bugs.

  • NBIRTH resets everything. When an edge node publishes a new NBIRTH, every alias table for that node is discarded and rebuilt from the new NBIRTH and the DBIRTHs that follow. An edge node is free to assign different alias numbers after a rebirth, so a consumer must never cache aliases across births.
  • NDEATH invalidates the table. When the broker publishes the edge node's NDEATH will message, consumers should mark the node's metrics stale and stop trusting the alias table until the next NBIRTH.
  • DBIRTH can add device metrics. A device can be rebirthed on its own, and its metrics' aliases must still be unique across the whole edge node.
  • Rebirth requests recover lost state. A host that sees an alias it does not know should send an NCMD with the Node Control/Rebirth metric set to true, rather than guessing. Our article on Sparkplug rebirth covers that flow in detail.

The sequence number helps too. Every Sparkplug message from an edge node carries a seq from 0 to 255 that wraps around. If a consumer sees a gap, it may have missed a BIRTH and should request a rebirth before trusting aliases again. The rules for BIRTH and DEATH messages are explained in Sparkplug birth and death certificates.

Decoding Aliased Data in Python

The following script subscribes to all Sparkplug traffic for one group, builds alias tables from NBIRTH and DBIRTH messages, and resolves DATA metrics back to names. It uses sparkplug_b_pb2.py, the generated Protobuf module from the Eclipse Tahu project; copy it next to the script and install the dependencies with pip install paho-mqtt protobuf.

import paho.mqtt.client as mqtt
import sparkplug_b_pb2

BROKER = "broker.connectmq.com"
GROUP = "demo-7f3k2"          # use your own unique group ID on the public broker
alias_tables = {}             # edge_node_id -> {alias: name}

def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    client.subscribe(f"spBv1.0/{GROUP}/#", qos=0)

def on_message(client, userdata, msg):
    parts = msg.topic.split("/")
    if len(parts) < 4:
        return
    msg_type, edge_node = parts[2], parts[3]
    device = parts[4] if len(parts) > 4 else None

    payload = sparkplug_b_pb2.Payload()
    payload.ParseFromString(msg.payload)

    if msg_type == "NBIRTH":
        alias_tables[edge_node] = {}          # a new NBIRTH resets all aliases
    if msg_type in ("NBIRTH", "DBIRTH"):
        table = alias_tables.setdefault(edge_node, {})
        for m in payload.metrics:
            if m.HasField("alias"):
                if m.alias in table and table[m.alias] != m.name:
                    print(f"WARNING duplicate alias {m.alias} on {edge_node}")
                table[m.alias] = m.name
        print(f"{msg_type} {edge_node}/{device or ''}: {len(alias_tables[edge_node])} aliases")
        return

    if msg_type == "NDEATH":
        alias_tables.pop(edge_node, None)
        print(f"NDEATH {edge_node}: alias table cleared")
        return

    if msg_type in ("NDATA", "DDATA"):
        table = alias_tables.get(edge_node)
        for m in payload.metrics:
            name = m.name
            if not name and m.HasField("alias"):
                if table is None or m.alias not in table:
                    print(f"UNKNOWN alias {m.alias} from {edge_node}, request a rebirth")
                    continue
                name = table[m.alias]
            value = getattr(m, m.WhichOneof("value")) if m.WhichOneof("value") else None
            print(f"{edge_node}/{device or ''} {name} = {value} (seq {payload.seq})")

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="alias-decoder-7f3k2")
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, keepalive=60)
client.loop_forever()

To produce test traffic with aliases, pair this with the publisher from our Sparkplug B edge node simulator tutorial. Both scripts work against the free public MQTT broker at broker.connectmq.com. Remember that the public broker is readable by anyone, so use a random group ID and never publish real plant data there.

Debugging Alias Mismatches

Most alias problems fall into a handful of patterns. Use this checklist when decoded values look wrong.

  1. Consumer started after the BIRTH. BIRTH messages are not retained in Sparkplug, so a consumer that connects later sees only aliased DATA. The fix is a rebirth request, or a primary host application that triggers rebirths automatically.
  2. Stale cache after a rebirth. If a consumer keeps its old table after a new NBIRTH, values land on the wrong names. Reset on every NBIRTH, as the script above does.
  3. Duplicate aliases across devices. Some edge configurations number aliases per device starting at 1. Two devices then both claim alias 1, which violates the uniqueness rule and corrupts any consumer that keys tables by edge node.
  4. Alias of zero treated as missing. In Protobuf, a field set to its default value can be indistinguishable from an absent field depending on how the code checks it. Starting aliases at 1 avoids an entire class of bugs.
  5. Mixed names and aliases. A DATA metric may legally include both name and alias. Consumers should prefer the name when present, and edge nodes should be consistent.
  6. Multiple publishers using one edge node ID. Two gateways configured with the same group and edge node ID overwrite each other's births. The symptom is aliases that flip between meanings.

Visual inspection speeds this up. ConnectMQ decodes Sparkplug B payloads, Protobuf or JSON, so in the portal's live topic explorer you can open the BIRTH and the DATA messages side by side and check that alias 12 really is the metric you expect. ConnectMQ can also republish Sparkplug B data into readable ISA-95 topics, for example spBv1.0/factory1/DDATA/line1/cnc1 into connectmq/factory1/production/line1/cnc1/telemetry, which gives non-Sparkplug consumers a path that does not depend on alias tables at all.

When Should You Enable Aliases?

Aliases are optional. Enable them when the link between edge and broker is metered or constrained, when tag counts are high and names are long, or when a single gateway publishes many metrics at a fast rate. Keep plain names when you are prototyping, when many lightweight consumers subscribe directly without a primary host, or when debuggability matters more than bytes.

A middle path works well for many teams: develop and commission with names, measure payload sizes under realistic load, and switch on aliases only on the sites whose links need it. Because aliases are negotiated entirely inside the BIRTH, consumers that implement the lookup correctly do not need any configuration change when you flip the switch.

For more context on where Sparkplug fits in a plant architecture, our industrial IoT MQTT guide covers the bigger picture, and the Sparkplug B payload article explains every field you saw in the decoded output above. The authoritative definition of alias behaviour is the Eclipse Sparkplug specification.

Test Sparkplug Aliases on ConnectMQ

Running edge nodes and host applications against a broker you control is the fastest way to validate alias handling before it reaches production. ConnectMQ is a managed MQTT broker with MQTT 3.1.1 and 5.0, TLS on port 8883 and built-in Sparkplug B decoding in the portal. Create a broker on the free Serverless plan at app.connectmq.com, no credit card required, then point your edge node at it with the generated username, password and client ID.

Frequently Asked Questions

Are Sparkplug metric aliases mandatory?

No. Aliases are optional in Sparkplug B. An edge node can send full metric names in every DATA message, and consumers must handle both forms.

Can alias numbers change between births?

Yes. Aliases are only valid until the next NBIRTH from that edge node. Consumers must rebuild their tables on every NBIRTH and never persist aliases across sessions.

What should a host do with an unknown alias?

It should not guess. The correct response is to send an NCMD with Node Control/Rebirth set to true so the edge node republishes its BIRTH messages and the full alias mapping.

Are Sparkplug aliases the same as MQTT 5 topic aliases?

No. Sparkplug metric aliases replace metric names inside the payload, while MQTT 5 topic aliases replace the topic string at the protocol level. They are independent and can be used together.

Related articles

IIoT Edge Gateway: What It Does and How to Choose One

An IIoT edge gateway connects machines that speak Modbus, OPC UA or proprietary protocols to MQTT and the cloud. Learn its core roles, common architectures and how to choose the right one.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.