Grundlagen

MQTT Retained Messages: So funktionieren sie und so löschst du sie

MQTT Retained Messages erklärt: wie das Retain-Flag funktioniert, wann du es nutzt, wie du eine Retained Message per leerer Payload löschst und MQTT-5-Optionen.

Aktualisiert · 6 Min. Lesezeit

Normalerweise leitet ein MQTT-Broker eine Nachricht an die Clients weiter, die gerade abonniert haben, und vergisst sie dann. Ein Client, der eine Minute später abonniert, sieht bis zum nächsten Publish nichts. Retained Messages lösen dieses Problem: Der Broker speichert die letzte Retained Message eines Topics und gibt sie jedem neuen Subscriber sofort weiter, sodass dieser immer mit dem aktuellen Zustand startet.

So funktionieren Retained Messages

Gesteuert wird das über ein einziges Bit, das RETAIN-Flag im PUBLISH-Paket. Erhält der Broker ein Publish mit RETAIN=1, passiert Folgendes:

  1. Er stellt die Nachricht wie gewohnt an die aktuellen Subscriber zu.
  2. Er speichert die Nachricht (Topic, Payload, QoS) als Retained Message für dieses Topic und ersetzt dabei eine eventuell vorhandene. Es gibt höchstens eine Retained Message pro Topic.
  3. Sobald ein Client später mit einem Filter abonniert, der auf das Topic passt, sendet der Broker die Retained Message direkt nach dem SUBACK – mit gesetztem Retain-Flag, damit der Client weiß, dass es sich um einen gespeicherten Wert handelt.
Zeitlicher Ablauf einer Retained Message
10:00  device   PUBLISH  acme/th-01/setpoint  "21.0"  retain=1   -> broker stores it
10:05  device   PUBLISH  acme/th-01/setpoint  "22.5"  retain=1   -> replaces "21.0"
10:30  app      SUBSCRIBE acme/+/setpoint
10:30  broker   PUBLISH  acme/th-01/setpoint  "22.5"  retain=1   -> delivered instantly

Wildcard-Subscriptions erhalten die Retained Messages jedes passenden Topics – so kann ein Dashboard, das acme/+/status abonniert, beim Start sofort den Zustand aller Geräte anzeigen.

Das Retain-Flag bei der Zustellung

In MQTT 3.1.1 ist das Retain-Flag bei Nachrichten, die an einen bestehenden Subscriber weitergeleitet werden, immer gelöscht; gesetzt ist es nur, wenn die Nachricht aufgrund einer neuen Subscription gesendet wird. MQTT 5 behält diesen Standard bei, ergänzt aber die Subscription-Option Retain As Published, die das ursprüngliche Flag erhält – nützlich für Bridges.

Ohne Retained Messages würde ein frisch gestartetes Dashboard leere Kacheln zeigen, bis jedes Gerät zufällig wieder publisht – was bei einem Türsensor oder einem Konfigurationswert Stunden dauern kann. Mit Retained Messages stimmt schon der erste Bildschirm.

Wann du Retained Messages einsetzen solltest

  • Gerätezustand – online/offline, an/aus, aktueller Modus.
  • Konfiguration und Sollwerte – ein Gerät, das neu startet, abonniert und bekommt sofort seine Konfiguration.
  • Sich langsam ändernde Werte – Firmware-Version, Standort, letzter bekannter Messwert.
  • Präsenz zusammen mit einer als Retained gesendeten Last-Will-Nachricht, damit der Offline-Status bestehen bleibt.

Nicht retainen solltest du:

  • Events und Befehle – ein gespeicherter unlock-door-Befehl würde jedem neuen Subscriber erneut zugestellt, womöglich Tage später.
  • Hochfrequente Streams – Retain schadet hier nicht, ist aber sinnlos, wenn der nächste Wert in einer Sekunde kommt.
  • Topics pro Nachricht – Topics mit IDs oder Zeitstempeln hinterlassen Tausende veralteter Retained Messages.

So löschst du eine Retained Message

Um eine Retained Message zu löschen, publishe an dasselbe Topic mit gesetztem Retain-Flag und einer Payload der Länge null. Der Broker entfernt die gespeicherte Nachricht und speichert die leere nicht. Aktuelle Subscriber erhalten die leere Nachricht allerdings, also sorge dafür, dass dein Code leere Payloads ignoriert.

Retained Message mit mosquitto_pub löschen
# -r = retain, -n = send a null (zero-length) payload
mosquitto_pub -h broker.hivemq.com -t 'testmqtt/demo/status' -r -n
Retained Message mit MQTT.js löschen
client.publish('testmqtt/demo/status', '', { retain: true, qos: 1 });

Um viele Topics auf einmal zu bereinigen, abonniere mit einer Wildcard, sammle jedes Topic, das eine Nachricht mit Retain-Flag liefert, und publishe an jedes davon eine leere Retained-Payload. Einen standardisierten Befehl „alle Retained Messages löschen“ gibt es nicht – manche Broker bieten Admin-Tools dafür an, die sind aber Broker-spezifisch.

Retained Messages vs. persistente Sessions

Retained Messages werden oft mit persistenten Sessions verwechselt, beantworten aber unterschiedliche Fragen:

Retained MessagePersistente Session
GeltungsbereichPro Topic, von allen Subscribern geteiltPro Client-ID
Was gespeichert wirdNur die letzte NachrichtSubscriptions plus jede verpasste QoS-1/2-Nachricht
Wer sie erhältJeder Client, der später abonniertNur dieser Client beim Reconnect
Typischer EinsatzAktueller ZustandKeine Events verpassen

Ein Gerät, das sowohl seine aktuelle Konfiguration als auch jeden Befehl braucht, der während seiner Offline-Zeit gesendet wurde, nutzt beides: ein Retained-Konfigurations-Topic und eine persistente Session für das Befehls-Topic. Der QoS-Guide erklärt, wie Sessions und QoS zusammenspielen.

Retained Messages behalten außerdem ihre QoS. Stellt der Broker eine gespeicherte Nachricht an einen neuen Subscriber zu, gilt die übliche Downgrade-Regel: Der Subscriber erhält sie mit der niedrigeren von ursprünglicher QoS und Subscription-QoS.

Retained Messages in MQTT 5

MQTT 5 bietet eine feinere Kontrolle über Retained Messages:

FeatureWas es bewirkt
Retain Handling (Subscription-Option)0 = Retained Messages beim Abonnieren senden (Standard), 1 = nur wenn die Subscription neu ist, 2 = nie senden
Retain As Published (Subscription-Option)Behält das ursprüngliche Retain-Flag bei weitergeleiteten Nachrichten bei
Message Expiry Interval (Publish-Property)Der Broker verwirft die Retained Message nach der angegebenen Anzahl Sekunden
Retain Available (CONNACK-Property)Teilt dem Client mit, ob der Broker Retained Messages überhaupt unterstützt

Message Expiry ist besonders praktisch: Ein gespeicherter Sensorwert, der nach einer Stunde abläuft, kann nie mit einem frischen verwechselt werden. Die vollständige Liste der Änderungen findest du unter MQTT 5 vs. 3.1.1.

Retained Messages testen

  1. Publishe online mit aktivierter Option Retain an testmqtt/your-id/status.
  2. Trenne die Verbindung, verbinde dich neu und abonniere testmqtt/your-id/#. Die Nachricht kommt sofort an, als Retained markiert.
  3. Publishe eine leere Payload mit aktiviertem Retain und abonniere erneut – nichts kommt an. Die Retained Message ist weg.

Im Online-MQTT-Client ausprobieren

Der Online-MQTT-Client zeigt bei gespeicherten Nachrichten ein Retained-Badge an, sodass du veralteten Zustand leicht erkennst. Eine umfassendere Checkliste findest du unter MQTT-Broker testen.

Häufig gestellte Fragen

Wie lösche ich eine Retained Message in MQTT?

Publishe an dasselbe Topic eine Nachricht mit gesetztem Retain-Flag und einer leeren Payload (Länge null). Der Broker entfernt die gespeicherte Retained Message, und die leere Nachricht wird nicht aufbewahrt. Mit mosquitto_pub nutzt du -r -n.

Wie viele Retained Messages kann ein Topic haben?

Eine. Der Broker speichert pro Topic nur die neueste Retained Message; jedes neue Retained-Publish ersetzt die vorherige.

Ist eine Retained Message dasselbe wie eine persistente Session?

Nein. Eine Retained Message ist der letzte Wert eines Topics und wird jedem neuen Subscriber zugestellt. Eine persistente Session puffert Nachrichten für einen bestimmten Client, solange er offline ist. Beide lösen unterschiedliche Probleme und werden oft zusammen eingesetzt.