MQTT über Mobilfunk ist der Weg, auf dem die meisten abgelegenen Anlagen (Pumpstationen und Hochbehälter von Stadtwerken, Tanks, Solarparks, Fahrzeuge, Umweltmessstationen) die Cloud erreichen, doch die Designregeln unterscheiden sich von WLAN oder Ethernet. Bytes werden abgerechnet, Verbindungen brechen häufiger ab, und Mobilfunknetze schließen inaktive Verbindungen stillschweigend. Dieser Leitfaden zeigt Ihnen, wie Sie ein Datenbudget schätzen, Keep-Alive-Werte wählen, den TLS-Overhead senken und zwischen LTE-M und NB-IoT entscheiden, damit Ihre Geräte verbunden bleiben, ohne dass böse Überraschungen auf der Rechnung folgen.
Warum Mobilfunk das MQTT-Design verändert
MQTT wurde ursprünglich für unzuverlässige Verbindungen mit geringer Bandbreite entworfen und passt daher bereits gut: ein 2 Byte großer fester Header, persistente TCP-Verbindungen und Publish-Subscribe, das Polling vermeidet. Drei Gegebenheiten des Mobilfunks prägen jedoch die Details:
- Jedes Byte wird abgerechnet, einschließlich TCP/IP-Headern, TLS-Records, Bestätigungen und Keep-Alive-Pings, nicht nur Ihr Payload.
- Carrier-Grade NAT sitzt zwischen den meisten Geräten und dem Internet und verwirft inaktive TCP-Zuordnungen nach einem netzbetreiberspezifischen Timeout. Bleibt MQTT länger still, stirbt die Verbindung, ohne dass eine der beiden Seiten es sofort bemerkt.
- Der Funkzustand kostet Strom. Jede Übertragung weckt das Modem, das danach noch eine Weile in einem stromintensiven Zustand bleibt. Viele kleine Sendungen leeren Batterien schneller als wenige gebündelte.
LTE-M vs. NB-IoT für MQTT
| LTE-M (Cat-M1) | NB-IoT (Cat-NB1/NB2) | |
|---|---|---|
| Durchsatz | Höher, komfortabel für MQTT über TLS | Sehr niedrig; große Handshakes dauern lange |
| Latenz | Vergleichbar mit normalem LTE, niedrig genug für interaktive Befehle | Hoch und schwankend, manchmal Sekunden |
| Mobilität | Unterstützt Handover zwischen Funkzellen | Für stationäre Geräte ausgelegt |
| Eignung für TCP/TLS | Gut | Möglich, aber oft mit UDP-basierten Protokollen kombiniert |
| Stromsparen | PSM und eDRX unterstützt | PSM und eDRX unterstützt, sehr geringer Ruhestrom |
| Abdeckung | Gut, besser als normales LTE | Hervorragend in Gebäudetiefen und unterirdischen Standorten |
Für MQTT über TCP und TLS ist LTE-M meist die pragmatische Wahl: TLS-Handshakes werden zuverlässig abgeschlossen, und Befehle erreichen das Gerät schnell. NB-IoT glänzt bei stationären Geräten, die kleine, seltene Meldungen von schwer erreichbaren Orten senden; dort nutzen viele Teams MQTT-SN oder ein anderes UDP-basiertes Protokoll oder nehmen bei MQTT über TCP einen langsamen Verbindungsaufbau in Kauf. Prüfen Sie vor der Hardwarewahl, welche Technologien Ihr Netzbetreiber in Ihrer Einsatzregion unterstützt; manche Modems beherrschen beides und wechseln automatisch.
Ein Datenbudget für MQTT über Mobilfunk schätzen
Die Payload-Größe ist oft der kleinste Posten auf der Rechnung. Berücksichtigen Sie:
- TCP/IP-Header auf jedem Paket (rund 40 Byte bei IPv4 ohne Optionen, mehr mit Optionen oder IPv6), plus TCP-Bestätigungen.
- TLS-Record-Overhead pro Nachricht, einige Dutzend Byte für Header, Nonce und Authentication Tag.
- MQTT-Overhead: fester Header, Topic-Name (oft der größte Teil einer kleinen Nachricht) und ein PUBACK bei QoS 1.
- Keep-Alive-Pings: PINGREQ und PINGRESP sind jeweils nur 2 Byte groß, doch mit TLS, TCP/IP-Headern und ACKs kostet jeder Umlauf auf der Leitung deutlich mehr.
- Verbindungsaufbau: Ein vollständiger TLS-Handshake einschließlich der Zertifikatskette des Servers umfasst typischerweise mehrere Kilobyte. Häufige Reconnects können das Budget dominieren.
Das folgende Skript liefert eine grobe Schätzung. Die Werte pro Paket sind bewusst konservative Annahmen; ersetzen Sie sie durch an Ihrem Modem gemessene Werte (die meisten Modems melden gesendete und empfangene Bytes).
# Grobe monatliche Datenschätzung für ein Mobilfunkgerät mit MQTT über TLS.
# Die Overhead-Werte sind Annahmen - messen Sie Ihre eigene Verbindung und passen Sie sie an.
PAYLOAD_BYTES = 60 # z. B. kompaktes JSON
TOPIC_BYTES = 40 # Länge des Topic-Strings
MSGS_PER_HOUR = 12 # ein Messwert alle 5 Minuten
QOS = 1 # QoS 1 fügt ein PUBACK hinzu
KEEPALIVE_S = 240 # Pings zählen nur, wenn die Verbindung sonst inaktiv ist
RECONNECTS_PER_DAY = 2 # jeder kostet einen vollständigen TLS-Handshake
TLS_HANDSHAKE_BYTES = 6000 # Annahme: die Zertifikatskette dominiert
TCP_IP_PER_PACKET = 52 # IPv4 + TCP mit Timestamps-Option
TLS_PER_RECORD = 29 # Record-Overhead bei TLS 1.2 AES-GCM
TCP_ACK = 52 # reines ACK-Paket
def bytes_per_publish():
mqtt = 2 + 2 + TOPIC_BYTES + (2 if QOS > 0 else 0) + PAYLOAD_BYTES
out = mqtt + TLS_PER_RECORD + TCP_IP_PER_PACKET
back = TCP_ACK
if QOS > 0:
back = 4 + TLS_PER_RECORD + TCP_IP_PER_PACKET + TCP_ACK # PUBACK + unser ACK
return out + back
def bytes_per_ping():
one_way = 2 + TLS_PER_RECORD + TCP_IP_PER_PACKET
return 2 * one_way + 2 * TCP_ACK
msgs = MSGS_PER_HOUR * 24 * 30
gap = 3600 / MSGS_PER_HOUR
pings_per_gap = int(gap // KEEPALIVE_S) # zwischen Nachrichten nötige Pings
pings = pings_per_gap * msgs
total = (msgs * bytes_per_publish()
+ pings * bytes_per_ping()
+ RECONNECTS_PER_DAY * 30 * TLS_HANDSHAKE_BYTES)
print(f"messages/month: {msgs}")
print(f"payload only: {msgs * PAYLOAD_BYTES / 1e6:.2f} MB")
print(f"estimated total: {total / 1e6:.2f} MB")
Die Ausführung zeigt das Muster, das Sie auch im Feld sehen werden: Die Gesamtmenge auf der Leitung beträgt ein Mehrfaches des reinen Payloads, und Topic-Länge, Bestätigungen und Reconnects zählen ebenso viel wie die Daten selbst. Deshalb konzentrieren sich die folgenden Optimierungen auf den Overhead.
Keep Alive vs. NAT-Timeouts der Netzbetreiber
Das MQTT-Keep-Alive-Intervall teilt dem Broker mit, wie lange der Client still bleiben darf. Wird sonst nichts gesendet, schickt der Client vor Ablauf des Intervalls ein PINGREQ. Im Mobilfunk hat Keep Alive eine zweite Aufgabe: die NAT-Zuordnung des Netzbetreibers am Leben zu halten.
- Ist Keep Alive länger als der NAT-Leerlauf-Timeout, wird die Zuordnung stillschweigend verworfen. Das Gerät hält sich weiterhin für verbunden; die nächste Veröffentlichung verschwindet, und die Verbindung wird erst nach einem TCP-Timeout als tot erkannt. Befehle aus der Cloud kommen in der Zwischenzeit nie an.
- Ist Keep Alive viel kürzer als nötig, bezahlen Sie für Pings, die Sie nicht brauchen, und halten das Funkmodul wach.
NAT-Timeouts unterscheiden sich zwischen Netzbetreibern und können nur wenige Minuten betragen. Messen Sie Ihren: Verbinden Sie sich mit einem langen Keep Alive, warten Sie zwischen Veröffentlichungen schrittweise länger und notieren Sie, wann Nachrichten aus der Cloud nicht mehr ankommen. Setzen Sie Keep Alive dann deutlich unter diesen Wert. Sendet das Gerät nur Daten und muss keine Befehle empfangen, gibt es eine Alternative: verbinden, veröffentlichen und trennen und dabei jedes Mal die Handshake-Kosten akzeptieren. Das kann günstiger sein, wenn Meldungen Stunden auseinanderliegen.
TLS-Kosten senken, ohne auf TLS zu verzichten
Senden Sie niemals Klartext-MQTT über ein öffentliches Mobilfunknetz. Machen Sie TLS stattdessen günstiger:
- Halten Sie Verbindungen offen, wenn Meldungen häufig sind, damit der Handshake selten stattfindet.
- Nutzen Sie TLS Session Resumption, wenn Ihr Modem oder Ihre TLS-Bibliothek Session-IDs oder Session Tickets unterstützt. Ein fortgesetzter Handshake überspringt den Zertifikatsaustausch und spart Bytes und Zeit.
- Bevorzugen Sie ECDHE mit ECDSA, wo beide Seiten es unterstützen; Schlüssel und Signaturen mit elliptischen Kurven sind kleiner als RSA-Äquivalente.
- Vertrauen Sie nur der Root, die Sie brauchen (zum Beispiel ISRG Root X1 für Let's-Encrypt-Zertifikate), damit das Gerät eine minimale Kette speichert und prüft.
- Vermeiden Sie Reconnect-Stürme. Verwenden Sie exponentielles Backoff mit Jitter, damit ein Funkzellenausfall nicht Hunderte direkt aufeinanderfolgender Handshakes auslöst.
Jede Nachricht verkleinern
- Kurze Topics. Ein Topic wie
t/pump7/pist bei jeder Veröffentlichung weit günstiger als eine lange, beschreibende Hierarchie. Mit MQTT 5 lassen Topic Aliases den Client das vollständige Topic einmal senden und danach über eine kleine Ganzzahl darauf verweisen, sodass lesbare Topics ohne Kosten pro Nachricht erhalten bleiben. - Kompakte Payloads. Kurze JSON-Schlüssel, Ganzzahlen mit impliziter Skalierung oder ein Binärformat wie Protobuf (wie es Sparkplug B nutzt).
- Messwerte bündeln. Senden Sie alle zehn Minuten zehn Messwerte in einer Nachricht statt einen pro Minute; die Header werden nur einmal bezahlt.
- Report by Exception. Senden Sie nur nennenswerte Änderungen plus einen Heartbeat; siehe Report by Exception.
- QoS-Wahl. QoS 1 fügt pro Nachricht ein PUBACK hinzu. Nutzen Sie es, wo die Zustellung wichtig ist, und QoS 0 für Werte mit hoher Rate, bei denen der nächste Messwert den letzten ersetzt.
In Industrie-4.0-Projekten entsteht dabei ein Zielkonflikt: Im Unified Namespace (UNS) folgen Topics der ISA-95-Hierarchie (Enterprise → Site → Area → Line → Cell), etwa acme/werk-stuttgart/aussenanlagen/pumpstation-7/pumpe-2/druck, und sind entsprechend lang. Auf der Funkstrecke lösen Topic Aliases das Problem; alternativ publiziert das Gerät kurze Topics, und ein Edge-Gateway oder ein Backend-Dienst ordnet die Daten in den UNS ein. Wie ein UNS aufgebaut ist, beschreibt der Leitfaden zu Sparkplug B und Unified Namespace.
MQTT-5-Session-Einstellungen für unterbrochene Verbindungen
Eine persistente Session lässt den Broker Abonnements behalten und QoS-1-Nachrichten für das Gerät zwischenspeichern, solange es kurz offline ist, sodass während eines Aussetzers gesendete Befehle nicht verloren gehen. Mit paho-mqtt 2.x:
import paho.mqtt.client as mqtt
from paho.mqtt.packettypes import PacketTypes
from paho.mqtt.properties import Properties
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id="YOUR_CLIENT_ID", protocol=mqtt.MQTTv5)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set() # CA-Speicher des Systems
client.reconnect_delay_set(min_delay=2, max_delay=300)
props = Properties(PacketTypes.CONNECT)
props.SessionExpiryInterval = 3600 # Session nach Abbruch 1 h behalten
client.connect("YOUR_BROKER_HOST", 8883, keepalive=240,
clean_start=False, properties=props)
client.loop_forever()
Kombinieren Sie das mit lokaler Pufferung für ausgehende Daten, denn eine Session schützt nur Nachrichten, die der Broker bereits empfangen hat. Der Leitfaden zu Store-and-Forward mit MQTT zeigt genau dafür eine festplattenbasierte Queue.
Checkliste für das Mobilfunk-Design
- Wählen Sie LTE-M für MQTT über TCP/TLS und interaktive Befehle; erwägen Sie NB-IoT für stationäre Geräte mit seltenen Meldungen.
- Messen Sie den NAT-Leerlauf-Timeout des Netzbetreibers und setzen Sie Keep Alive darunter.
- Behalten Sie TLS bei, minimieren Sie aber Handshakes und nutzen Sie Session Resumption, wo verfügbar.
- Kürzen Sie Topics oder nutzen Sie Topic Aliases aus MQTT 5; komprimieren und bündeln Sie Payloads.
- Wenden Sie Report by Exception am Edge an.
- Puffern Sie ausgehende Daten während Ausfällen auf dem Gerät.
- Verwenden Sie für Reconnects exponentielles Backoff mit Jitter.
- Überwachen Sie die Bytes pro Gerät und Tag, damit Auffälligkeiten vor der Rechnung sichtbar werden.
Ein praktisches Modem-Beispiel finden Sie unter SIM7600 MQTT. Zur Architektur auf Gateway-Ebene lesen Sie über das IIoT-Edge-Gateway und den Leitfaden zu Industrial IoT mit MQTT.
Testen, bevor Sie für Daten bezahlen
Validieren Sie Topic-Struktur und Payload-Format zuerst über WLAN oder Ethernet, auf dem öffentlichen MQTT-Broker mit einem eindeutigen Präfix wie connectmq/demo/cell-4f8a/...; er ist für Tests gedacht, nicht für Produktionsdaten. Bringen Sie das Gerät anschließend mit produktiven Zugangsdaten auf einem verwalteten MQTT-Broker wie ConnectMQ in den Mobilfunk, der TLS-Endpunkte und MQTT-5-Funktionen bereitstellt, ohne dass Sie Server betreiben müssen. Sie vergleichen Hosting-Optionen? Der Leitfaden zum Cloud-MQTT-Broker zeigt, worauf Sie achten sollten.
Verbinden Sie Ihre Mobilfunkflotte mit ConnectMQ
ConnectMQ unterstützt MQTT 3.1.1 und 5.0 über TLS auf Port 8883, mit Session Expiry, Topic Aliases und Message Expiry für unterbrochene Verbindungen. Das Topic $SYS/broker/connection/{clientId}/state und die Geräteansichten im Portal zeigen Ihnen, welche abgelegenen Geräte online sind. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte.
Häufig gestellte Fragen
Wie viele Daten verbraucht MQTT über Mobilfunk?
Das hängt weit mehr vom Overhead als vom Payload ab: TCP/IP- und TLS-Header, Bestätigungen, Keep-Alive-Pings und Reconnect-Handshakes. Schätzen Sie mit einem Modell wie dem obigen Skript und prüfen Sie das Ergebnis anschließend mit den Byte-Zählern Ihres Modems.
Welchen Keep Alive sollte ich bei LTE-M verwenden?
Einen kürzeren als den NAT-Leerlauf-Timeout Ihres Netzbetreibers, den Sie messen sollten. Werte von einigen Minuten sind übliche Ausgangspunkte; passen Sie sie nach dem Testen an.
Eignet sich NB-IoT für MQTT?
Für kleine, seltene Nachrichten von stationären Geräten kann es funktionieren, doch hohe Latenz und geringer Durchsatz machen TCP- und TLS-Handshakes langsam. LTE-M passt besser zu Standard-MQTT über TLS.
Sollten Mobilfunkgeräte zwischen Meldungen die Verbindung trennen?
Liegen Meldungen Stunden auseinander und müssen keine Befehle das Gerät erreichen, kann Verbinden-Veröffentlichen-Trennen günstiger sein. Bei häufigen Meldungen oder Fernsteuerung halten Sie die Verbindung mit einem abgestimmten Keep Alive offen.



