Die Wahl des MQTT-Payload-Formats gehört zu den ersten Designentscheidungen jedes IoT-Projekts – und zu denen, die sich später am schwersten ändern lassen. MQTT behandelt den Payload als opake Bytes, also funktionieren JSON, Protobuf, CBOR oder ein eigenes Binärlayout gleichermaßen auf der Leitung. Dieser Vergleich zeigt anhand der Bytezahlen für dieselbe Sensornachricht, wie sich die drei gängigsten Kodierungen bei Größe, Schema-Verwaltung und Tooling unterscheiden, damit Sie die richtige für Ihre Geräte wählen.
MQTT ist Payload-agnostisch
Ein MQTT-PUBLISH-Paket enthält ein Topic, einige Flags, optionale MQTT-5-Properties und einen Payload von laut Protokoll bis zu 256 MB (Broker setzen in der Praxis deutlich niedrigere Grenzen durch). Der MQTT-Broker schaut nie in den Payload hinein. Das gibt Ihnen Freiheit, bedeutet aber auch, dass nichts zwei Teams daran hindert, inkompatible Formate auf dasselbe Topic zu publizieren.
MQTT 5 ergänzt zwei hilfreiche Properties:
- Payload Format Indicator: 0 bedeutet nicht spezifizierte Bytes, 1 bedeutet UTF-8-Text.
- Content Type: ein frei wählbarer String, typischerweise ein MIME-Typ wie
application/jsonoderapplication/x-protobuf.
Sie zu setzen kostet ein paar Bytes und erlaubt generischen Tools, Loggern und Konsumenten, Ihre Nachrichten korrekt zu verarbeiten.
Die Beispielnachricht
Für einen fairen Vergleich kodieren wir denselben Pumpenmesswert in jedem Format:
{"deviceId":"pump-07","ts":1760600000,"temp":21.5,"pressure":2.31,"rpm":1480,"running":true}
Sechs Felder: eine String-ID, ein Unix-Zeitstempel, zwei Dezimalmesswerte, eine Ganzzahl und ein Boolean. Das ist eine realistische Struktur für Industrie- und Gebäudetelemetrie.
Größenvergleich
Die folgenden Bytezahlen sind aus den Kodierungsregeln jedes Formats für genau diese Nachricht berechnet:
| Kodierung | Bytes | Hinweise |
|---|---|---|
| JSON, formatiert (2 Leerzeichen Einzug) | 117 | Menschenfreundlich, verschwenderisch auf der Leitung |
| JSON, kompakt | 92 | Der übliche Standard |
| JSON, kompakt mit kurzen Schlüsseln | 65 | {"d":"pump-07","t":1760600000,"tp":21.5,"p":2.31,"r":1480,"on":1} |
| CBOR, Gleitkommazahlen als 64 Bit | 74 | Dieselben Schlüssel wie JSON, binäre Werte |
| CBOR, Gleitkommazahlen als 32 Bit | 64 | Präzisionsverlust bei pressure |
Protobuf, Gleitkommazahlen als float |
30 | Feldnummern statt Namen |
Einige Beobachtungen:
- Den Großteil der JSON-Größe machen Schlüsselnamen und Zahlen als Text aus. Kürzere Schlüssel bringen viel, bevor Sie überhaupt das Format wechseln.
- CBOR behält die selbstbeschreibende Map-Struktur bei, Schlüsselnamen reisen also weiterhin mit jeder Nachricht. Die Einsparungen kommen von binären Zahlen und Booleans.
- Protobuf ist klein, weil die Feldnamen in einer Schema-Datei liegen und nicht in der Nachricht. Der Empfänger muss dieses Schema besitzen.
Denken Sie an MQTT-Header und Topic zusätzlich zum Payload. Ein Topic wie site/plant1/line1/pump-07/telemetry hat 35 Bytes und ist damit größer als der gesamte Protobuf-Payload. Wenn Bandbreite wirklich zählt, betrachten Sie auch Topic-Länge und Topic Aliases aus MQTT 5, nicht nur die Kodierung. In Industrie-4.0-Projekten bildet die Topic-Struktur meist einen Unified Namespace (UNS) nach der ISA-95-Hierarchie ab, etwa acme/werk-stuttgart/montage/linie-1/zelle-3/pumpe-07. Das Topic trägt dann den Kontext (Werk, Bereich, Linie, Zelle), und der Payload kann sich auf die Messwerte beschränken. Ein einheitliches Payload-Format im gesamten UNS ist mindestens so wichtig wie die Wahl der Kodierung selbst. Einen breiteren Blick darauf, wohin die Bytes gehen, bietet MQTT-Bandbreitennutzung.
JSON: Aus gutem Grund der Standard
JSON gewinnt in allem außer der Größe:
- In jedem MQTT-Client, jeder Logdatei und jedem Terminal lesbar.
- Jede Sprache und Plattform hat einen Parser, einschließlich ArduinoJson auf Mikrocontrollern.
- Node-RED, Telegraf, Home Assistant und die meisten Dashboards akzeptieren es ohne Konfiguration.
- Ein neues Feld bricht ältere Konsumenten selten.
Seine Schwächen: keine Schema-Durchsetzung, mehrdeutige Zahlentypen (ist 1 ein Boolean, eine Ganzzahl oder eine Gleitkommazahl?) und Parsing-Aufwand auf sehr kleinen Mikrocontrollern. Für die meisten Projekte mit netzbetriebenen Geräten und WLAN oder Ethernet sind diese Kompromisse akzeptabel.
Protobuf: Am kleinsten, mit Schema
Protocol Buffers kodieren jedes Feld als Feldnummer plus kompakten Wert. Das Schema für unsere Nachricht:
syntax = "proto3";
message PumpReading {
string device_id = 1;
uint64 ts = 2;
float temp = 3;
float pressure = 4;
uint32 rpm = 5;
bool running = 6;
}
Stärken: kleinste Payloads, starke Typisierung, generierter Code in vielen Sprachen und klar definierte Regeln für die Schema-Weiterentwicklung (Felder mit neuen Nummern hinzufügen, alte Nummern nie wiederverwenden). Sparkplug B, im industriellen MQTT weit verbreitet, basiert genau aus diesen Gründen auf Protobuf; siehe MQTT Sparkplug B und der Unified Namespace.
Schwächen: ohne Schema unlesbar, das Debugging braucht also Dekodierwerkzeuge; Schema-Dateien müssen an jeden Produzenten und Konsumenten verteilt und versioniert werden; und generische Integrationen können die Daten ohne Dekodierschritt nicht nutzen.
CBOR: Binäres JSON
CBOR (RFC 8949) behält das Datenmodell von JSON – Maps, Arrays, Strings und Zahlen – bei, kodiert es aber binär. Es braucht kein Schema, sodass jeder CBOR-Decoder eine Nachricht wieder in eine JSON-ähnliche Struktur verwandeln kann.
Stärken: kleiner als JSON, selbstbeschreibend, native binäre Byte-Strings (kein Base64) und beliebt in ressourcenbeschränkten Protokollen wie CoAP. Schwächen: Die Einsparungen sind moderat, sofern Sie nicht auch Schlüssel kürzen, die Tool-Unterstützung ist dünner als bei JSON, und die Gleitkomma-Kodierung unterscheidet sich zwischen Bibliotheken, was beim Vergleichen von Bytes überraschen kann.
Entscheidungs-Checkliste
- Werden Menschen diese Nachrichten oft lesen? JSON bevorzugen.
- Laufen Geräte über getaktetes Mobilfunk-, LoRa-Backhaul- oder Satellitennetz? Protobuf erwägen oder als ersten Schritt kompaktes JSON mit kurzen Schlüsseln.
- Konsumieren viele Teams und Sprachen dieselben Daten? Protobuf-Schemas zahlen sich aus; andernfalls JSON mit dokumentiertem Schema.
- Brauchen Sie Binär-Blobs in strukturierten Daten? CBOR verarbeitet sie nativ.
- Integration mit Standard-Tools? JSON, oder einen Dekodierschritt einplanen, der JSON neu publiziert.
- Industrielle Interoperabilität? Sparkplug B prüfen, bevor Sie ein eigenes Protobuf-Schema erfinden. Kommen die Daten aus OPC-UA-Servern an der SPS, lohnt auch ein Blick auf OPC UA PubSub, das eigene Kodierungen für den Transport über MQTT definiert.
Was auch immer Sie wählen: Versionieren Sie es. Ein schema-Feld im Payload, eine Version im Topic oder eine User Property aus MQTT 5 funktionieren alle; wichtig ist, dass Konsumenten Formate unterscheiden können.
Mit Content Type in Python publizieren
Dieses Beispiel mit paho-mqtt 2.x publiziert den kompakten JSON-Messwert mit gesetztem MQTT-5-Payload-Format-Indicator und Content Type an den öffentlichen MQTT-Broker, der für Tests und Prototypen gedacht ist, nicht für Produktionsdaten:
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()
Beachten Sie separators=(",", ":"): Das standardmäßige json.dumps von Python fügt nach jedem Komma und Doppelpunkt ein Leerzeichen ein, wodurch der Payload größer würde als der kompakte Wert in der Tabelle.
Fallstricke beim Payload
- Formate auf einem Topic mischen. Konsumenten brechen auf verwirrende Weise. Ein Topic, ein Format.
- Überraschungen mit Gleitkommazahlen. 32-Bit-Floats können 2,31 nicht exakt darstellen. Legen Sie die Präzision bewusst fest oder senden Sie skalierte Ganzzahlen.
- Zeitstempel in Ortszeit. Verwenden Sie UTC-Unix-Zeit oder ISO 8601 mit Offset.
- Größenlimits überschreiten. Werden viele Messwerte in einer Nachricht gebündelt, kann das die maximale Nachrichtengröße des Brokers erreichen; siehe das MQTT-Limit für die Nachrichtengröße.
Payload-Formate auf ConnectMQ
ConnectMQ transportiert jedes Payload-Format, da MQTT-Payloads opake Bytes sind. Darüber hinaus kann ConnectMQ Sparkplug-B-Payloads (Protobuf oder JSON) dekodieren und in lesbare ISA-95-Topics des UNS neu publizieren. Die Nachrichtenlimits betragen 256 KB im kostenlosen Serverless-Plan und 1 MB im kostenpflichtigen Serverless-Plan – reichlich für jede der obigen Kodierungen eines einzelnen Messwerts. Wenn Sie die Infrastruktur lieber nicht selbst betreiben, lässt Sie ein verwalteter MQTT-Broker auf die Payload-Vereinbarung konzentrieren. Das MQTT-Tutorial behandelt den Rest des Protokolls.
Starten Sie mit ConnectMQ
Erstellen Sie unter app.connectmq.com einen kostenlosen Broker im Serverless-Plan, ganz ohne Kreditkarte. Publizieren Sie denselben Messwert in JSON und im Binärformat Ihrer Wahl und vergleichen Sie beide nebeneinander im browserbasierten Client des ConnectMQ-Portals.
Häufig gestellte Fragen
Was ist das beste MQTT-Payload-Format?
Das eine beste gibt es nicht. JSON ist die sicherste Standardwahl für Interoperabilität und Debugging; Protobuf ist am besten, wenn die Bandbreite knapp ist und Schemas gut verwaltet werden.
Validiert der Broker das Payload-Format?
Nein. MQTT-Broker behandeln Payloads als opake Bytes. Die Validierung findet in Ihren Konsumenten statt.
Sollte ich JSON-Payloads komprimieren?
Bei einzelnen kleinen Messwerten spart Kompression oft wenig und kostet CPU. Bei großen gebündelten Nachrichten hilft sie mehr.
Wie teile ich Konsumenten mit, welches Format eine Nachricht verwendet?
In MQTT 5 setzen Sie die Property Content Type. In MQTT 3.1.1 nutzen Sie eine Topic-Konvention oder ein Versionsfeld im Payload.



