Industrial IoT

Sparkplug B Data Types and Metric Properties Reference

A practical reference to every Sparkplug B data type, the Protobuf field each one travels in, metric properties such as Quality, metric flags and DataSets, with decoded examples and common conversion mistakes.

Reference chart of Sparkplug B data types with codes, Protobuf value fields and metric properties
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 B data types define exactly how each metric value is encoded, from an 8-bit signed integer to a full table of rows and columns. This reference lists every datatype code with the Protobuf field it uses, explains metric properties and quality codes, and shows decoded examples so you can recognise each type when you inspect real traffic.

Why Sparkplug Has Its Own Data Types

JSON has numbers, strings and booleans. Industrial systems need more precision than that. A PLC register might be an unsigned 16-bit integer, a counter might be a 64-bit unsigned value, and a timestamp must not be confused with an ordinary number. Sparkplug B gives every metric an explicit datatype code so that a host application on the other side of the world interprets the value exactly as the edge node intended.

The datatype is declared for every metric in birth messages. Data messages can omit it, which is why consumers store datatypes from the births, as described in our Sparkplug B payload guide.

Scalar Sparkplug B Data Types

Code Name Protobuf value field Notes
0 Unknown none Placeholder, should not appear in valid metrics
1 Int8 int_value Signed, two's complement in an unsigned field
2 Int16 int_value Signed, two's complement
3 Int32 int_value Signed, two's complement
4 Int64 long_value Signed, two's complement in uint64
5 UInt8 int_value Unsigned
6 UInt16 int_value Unsigned
7 UInt32 int_value Unsigned
8 UInt64 long_value Unsigned
9 Float float_value 32-bit IEEE 754
10 Double double_value 64-bit IEEE 754
11 Boolean boolean_value true or false
12 String string_value UTF-8 text
13 DateTime long_value Milliseconds since Unix epoch, UTC
14 Text string_value Longer text, same encoding as String
15 UUID string_value UUID in string form
16 DataSet dataset_value Table of typed columns and rows
17 Bytes bytes_value Raw binary data
18 File bytes_value File content, described by MetaData
19 Template template_value User-defined type or instance

Codes 20 and 21 (PropertySet and PropertySetList) are used for property values, not metric values.

The signed integer trap

The most common decoding bug in Sparkplug is reading signed integers directly. Because int_value is an unsigned 32-bit field, an Int32 of -5 arrives as 4294967291, and an Int64 of -1 arrives as 18446744073709551615 in long_value. The consumer must apply two's complement using the declared datatype. Edge nodes must do the reverse when encoding. If a dashboard suddenly shows a temperature of four billion degrees, this is almost always the reason.

DateTime is not a number

A DateTime metric and an Int64 metric use the same field, but they mean different things. Treat DateTime as milliseconds since the epoch in UTC and convert it for display. Never send seconds, and never send local time.

Array Data Types

Sparkplug also defines arrays of scalar types. They travel in bytes_value as packed little-endian values, an encoding that Sparkplug 3.0 spells out precisely (see our Sparkplug 3.0 comparison for what else was clarified).

Code Name Code Name
22 Int8Array 29 UInt64Array
23 Int16Array 30 FloatArray
24 Int32Array 31 DoubleArray
25 Int64Array 32 BooleanArray
26 UInt8Array 33 StringArray
27 UInt16Array 34 DateTimeArray
28 UInt32Array

Array support varies between products. If you depend on arrays across vendors, test them early with both ends connected to the same broker.

Metric Flags

Each metric can carry boolean flags that change how consumers treat it:

Flag Meaning Consumer behaviour
is_null The metric exists but has no value Show as null or bad quality, do not substitute zero
is_historical Value is from the past, for example store and forward Store it, do not overwrite the live value
is_transient Value should not be historized Display it, do not store it

Metrics also have an optional timestamp, separate from the payload timestamp. Use it to record when the value was sampled at the source.

Metric Properties

A metric can carry a PropertySet: parallel lists of keys and typed values. Property values use the same datatype codes plus PropertySet (20) and PropertySetList (21), which allow nesting.

The Quality property

The one property the specification gives a defined meaning is Quality, an Int32:

Value Meaning
192 Good
0 Bad
500 Stale

A host that receives a metric with Quality 0 should display it as bad, even if a value is present. Many edge platforms set Quality 500 when they lose contact with the underlying device but still keep the node connected.

Other common properties

Engineering units, ranges, descriptions and display formats are frequently carried as properties, but their key names are conventions of each platform rather than part of the specification. Agree on a property vocabulary across your edge nodes, or your host application will see the same concept under different keys.

DataSets

A DataSet is a small typed table inside a single metric. It has a column count, column names, a datatype code for each column and a list of rows. Each row value uses a restricted set of fields: int, long, float, double, boolean or string.

Decoded, a recipe parameter table might look like this:

{
  "name": "Recipe/Steps",
  "datatype": 16,
  "datasetValue": {
    "numOfColumns": 3,
    "columns": ["Step", "Temperature", "Duration"],
    "types": [3, 9, 7],
    "rows": [
      { "elements": [{ "intValue": 1 }, { "floatValue": 180.0 }, { "intValue": 600 }] },
      { "elements": [{ "intValue": 2 }, { "floatValue": 220.0 }, { "intValue": 300 }] }
    ]
  }
}

DataSets are useful for batches of related values that must stay together. For structured equipment models, templates are usually a better fit; see Sparkplug templates and UDTs.

Decoded Examples

Here is a birth fragment with several data types and a Quality property, as you would see it after decoding:

[
  { "name": "Pump/Running", "alias": 1, "datatype": 11, "booleanValue": true },
  { "name": "Pump/Speed", "alias": 2, "datatype": 9, "floatValue": 1475.0,
    "properties": { "keys": ["Quality"], "values": [{ "type": 3, "intValue": 192 }] } },
  { "name": "Pump/StartCount", "alias": 3, "datatype": 8, "longValue": "18342" },
  { "name": "Pump/LastService", "alias": 4, "datatype": 13, "longValue": "1789000000000" },
  { "name": "Pump/Offset", "alias": 5, "datatype": 2, "intValue": 4294967286 },
  { "name": "Pump/Serial", "alias": 6, "datatype": 12, "stringValue": "P-0042" }
]

Note the Int16 offset: the raw value 4294967286 is -10 after two's complement. Also note that some JSON renderings show 64-bit values as strings to avoid precision loss in JavaScript.

Checking Data Types in Practice

The quickest way to verify datatypes is to read decoded births. ConnectMQ decodes Sparkplug B in the portal topic explorer, so you can open an NBIRTH or DBIRTH and check each metric's datatype and value without writing code. For automated checks, the decoder in our tutorial on how to decode Sparkplug B in Python maps codes to names and handles signed conversion.

When you test on the public MQTT test broker, use a random group ID and remember everything there is readable by everyone.

Data Type Checklist for Edge Node Configuration

  1. Match each Sparkplug type to the source register type; do not widen everything to Double.
  2. Use unsigned types for counters that never go negative.
  3. Use DateTime for timestamps, always in milliseconds UTC.
  4. Set Quality on metrics whose source can fail independently of the node.
  5. Use is_null rather than zero when a value is unavailable.
  6. Flag store-and-forward data as historical.
  7. Agree on property key names across all edge nodes.
  8. Test arrays, DataSets and templates end to end before rollout.

Where Data Types Fit

Correct data types are what let Sparkplug data feed historians, SCADA and a Unified Namespace without per-tag fixes. For architecture guidance, see the Industrial IoT with MQTT guide. Any compliant MQTT broker carries these payloads; a fully managed MQTT service that also decodes them makes verification much faster.

Get Started with ConnectMQ

Create a free Serverless broker at app.connectmq.com, no credit card required. Connect your edge node and check every metric's datatype, value and quality in the ConnectMQ topic explorer.

Frequently Asked Questions

How many Sparkplug B data types are there?

The specification defines scalar types with codes 1 to 19, property set types 20 and 21, and array types 22 to 34. Code 0 is Unknown.

Why is my negative Sparkplug value showing as a huge number?

Signed integers are stored in unsigned Protobuf fields. Apply two's complement based on the declared datatype, or use a decoder that does it for you.

What does Quality 192 mean in Sparkplug?

It means good quality. The Quality property uses 192 for good, 0 for bad and 500 for stale.

Are Sparkplug data types required in data messages?

They are required in birth messages and optional in NDATA and DDATA. Consumers should remember each metric's datatype from the birth.

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.