MQTT Fundamentals

MQTT Payload Formats: JSON vs Protobuf vs CBOR

MQTT does not care what is inside a payload, so the choice is yours. Compare JSON, Protobuf and CBOR on size, schemas, debugging and tooling, using byte counts for the same sensor reading.

Same sensor reading encoded as JSON, Protobuf and CBOR, comparing MQTT payload format sizes
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

Choosing an MQTT payload format is one of the first design decisions in any IoT project, and one of the hardest to change later. MQTT treats the payload as opaque bytes, so JSON, Protobuf, CBOR or a custom binary layout all work on the wire. This comparison shows how the three most common encodings differ in size, schema management and tooling, using byte counts for the same sensor message, so you can pick the right one for your devices.

MQTT Is Payload-Agnostic

An MQTT PUBLISH packet contains a topic, some flags, optional MQTT 5 properties and a payload of up to 256 MB by protocol limit (brokers enforce much lower limits in practice). The MQTT broker never looks inside the payload. That gives you freedom, but it also means nothing stops two teams from publishing incompatible formats to the same topic.

MQTT 5 adds two properties that help:

  • Payload Format Indicator: 0 means unspecified bytes, 1 means UTF-8 text.
  • Content Type: a free-form string, typically a MIME type such as application/json or application/x-protobuf.

Setting them costs a few bytes and lets generic tools, loggers and consumers handle your messages correctly.

The Sample Message

To compare fairly we encode the same pump reading in each format:

{"deviceId":"pump-07","ts":1760600000,"temp":21.5,"pressure":2.31,"rpm":1480,"running":true}

Six fields: a string ID, a Unix timestamp, two decimal measurements, an integer and a boolean. That is a realistic shape for industrial and building telemetry.

Size Comparison

The byte counts below are calculated from the encoding rules of each format for this exact message:

Encoding Bytes Notes
JSON, pretty-printed (2-space indent) 117 Human-friendly, wasteful on the wire
JSON, compact 92 The common default
JSON, compact with short keys 65 {"d":"pump-07","t":1760600000,"tp":21.5,"p":2.31,"r":1480,"on":1}
CBOR, floats as 64-bit 74 Same keys as JSON, binary values
CBOR, floats as 32-bit 64 Precision trade-off on pressure
Protobuf, floats as float 30 Field numbers instead of names

A few observations:

  • Most of JSON's size is the key names and number text. Shortening keys gets you a long way before you change formats at all.
  • CBOR keeps the self-describing map structure, so key names still travel with every message. Its savings come from binary numbers and booleans.
  • Protobuf is small because the field names live in a schema file, not in the message. The receiver must have that schema.

Remember the MQTT header and topic on top of the payload. A topic like site/plant1/line1/pump-07/telemetry is 35 bytes, which is larger than the entire Protobuf payload. If bandwidth really matters, look at topic length and MQTT 5 topic aliases too, not just encoding. For a broader view of where bytes go, see MQTT bandwidth usage.

JSON: The Default for Good Reasons

JSON wins on everything except size:

  • Readable in any MQTT client, log file or terminal.
  • Every language and platform has a parser, including ArduinoJson on microcontrollers.
  • Node-RED, Telegraf, Home Assistant and most dashboards accept it without configuration.
  • Adding a field rarely breaks older consumers.

Its weaknesses: no schema enforcement, ambiguous number types (is 1 a boolean, an integer or a float?), and parsing cost on very small microcontrollers. For most projects with mains-powered devices and Wi-Fi or Ethernet, those trade-offs are acceptable.

Protobuf: Smallest, with a Schema

Protocol Buffers encode each field as a field number plus a compact value. The schema for our message:

syntax = "proto3";

message PumpReading {
  string device_id = 1;
  uint64 ts = 2;
  float temp = 3;
  float pressure = 4;
  uint32 rpm = 5;
  bool running = 6;
}

Strengths: smallest payloads, strong typing, generated code in many languages, and well-defined rules for evolving schemas (add fields with new numbers, never reuse old ones). Sparkplug B, widely used in industrial MQTT, is built on Protobuf for exactly these reasons; see MQTT Sparkplug B and the Unified Namespace.

Weaknesses: unreadable without the schema, so debugging needs decoding tools; schema files must be distributed and versioned across every producer and consumer; and generic integrations cannot use the data without a decode step.

CBOR: Binary JSON

CBOR (RFC 8949) keeps JSON's data model, maps, arrays, strings and numbers, but encodes it in binary. It needs no schema, so any CBOR decoder can turn a message back into a JSON-like structure.

Strengths: smaller than JSON, self-describing, native binary byte strings (no base64), and popular in constrained protocols such as CoAP. Weaknesses: savings are moderate unless you also shorten keys, tool support is thinner than for JSON, and float encoding differs between libraries, which can surprise you when you compare bytes.

Decision Checklist

  1. Are humans going to read these messages often? Prefer JSON.
  2. Are devices on metered cellular, LoRa backhaul or satellite? Consider Protobuf, or compact JSON with short keys as a first step.
  3. Many teams and languages consuming the same data? Protobuf's schemas pay for themselves; otherwise JSON with a documented schema.
  4. Need binary blobs inside structured data? CBOR handles them natively.
  5. Integrating with off-the-shelf tools? JSON, or plan a decode step that republishes JSON.
  6. Industrial interoperability? Look at Sparkplug B before inventing your own Protobuf schema.

Whatever you choose, version it. A schema field in the payload, a version in the topic, or an MQTT 5 user property all work; the important thing is that consumers can tell formats apart.

Publishing with Content Type in Python

This paho-mqtt 2.x example publishes the compact JSON reading with the MQTT 5 payload format indicator and content type set, to the public MQTT test broker:

import json
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes

reading = {"deviceId": "pump-07", "ts": 1760600000, "temp": 21.5,
           "pressure": 2.31, "rpm": 1480, "running": True}
payload = json.dumps(reading, separators=(",", ":")).encode()
print("payload bytes:", len(payload))  # 92

props = Properties(PacketTypes.PUBLISH)
props.PayloadFormatIndicator = 1
props.ContentType = "application/json"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"fmt-{uuid.uuid4().hex[:8]}",
                     protocol=mqtt.MQTTv5)
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_start()
client.publish("connectmq/demo/f6n1/pump-07/telemetry", payload,
               qos=1, properties=props).wait_for_publish()
client.loop_stop()
client.disconnect()

Note separators=(",", ":"): Python's default json.dumps adds a space after every comma and colon, which would make the payload larger than the compact figure in the table.

Payload Pitfalls

  • Mixing formats on one topic. Consumers break in confusing ways. One topic, one format.
  • Floating-point surprises. 32-bit floats cannot represent 2.31 exactly. Decide on precision deliberately or send scaled integers.
  • Timestamps in local time. Use UTC Unix time or ISO 8601 with an offset.
  • Exceeding size limits. Batching many readings into one message can hit the broker's maximum message size; see the MQTT message size limit.

Payload Formats on ConnectMQ

ConnectMQ carries any payload format, since MQTT payloads are opaque bytes. On top of that, ConnectMQ can decode Sparkplug B payloads (Protobuf or JSON) and republish them into readable ISA-95 topics. Message limits are 256 KB on the free Serverless plan and 1 MB on the paid Serverless plan, which is ample for any single-reading encoding above. If you would rather not operate the infrastructure, a managed MQTT broker lets you focus on the payload contract. The MQTT tutorial covers the rest of the protocol.

Get Started with ConnectMQ

Create a free broker at app.connectmq.com on the Serverless plan, no credit card required. Publish the same reading in JSON and in your binary format of choice, and compare them side by side in the in-browser client of the ConnectMQ portal.

Frequently Asked Questions

What is the best MQTT payload format?

There is no single best. JSON is the safest default for interoperability and debugging; Protobuf is best when bandwidth is tight and schemas are managed well.

Does the broker validate the payload format?

No. MQTT brokers treat payloads as opaque bytes. Validation happens in your consumers.

Should I compress JSON payloads?

For single small readings, compression often saves little and costs CPU. It helps more for large batched messages.

How do I tell consumers which format a message uses?

In MQTT 5, set the Content Type property. In MQTT 3.1.1, use a topic convention or a version field inside the payload.

Related articles

Why Your MQTT Client Keeps Disconnecting (and How to Fix It)

Reconnect loops are one of the most common MQTT problems. Learn the five usual causes, from duplicate client IDs to keep alive timeouts and oversized packets, and follow a diagnosis flow that pinpoints yours.

8 min read

Who Invented MQTT? The History from Oil Pipelines to IoT

MQTT was invented in 1999 by Andy Stanford-Clark of IBM and Arlen Nipper of Arcom to monitor oil pipelines over satellite. Follow its path to open source, OASIS, ISO and today's managed cloud brokers.

7 min read

MQTT Maximum Message Size: Limits and Large Payload Strategies

MQTT can technically carry a 256 MB packet, but brokers, client libraries and devices impose far lower limits. Learn where the real limits are, what happens when you exceed them, and how to send large payloads.

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.