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:
- Er stellt die Nachricht wie gewohnt an die aktuellen Subscriber zu.
- 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.
- 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.
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 instantlyWildcard-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.
# -r = retain, -n = send a null (zero-length) payload
mosquitto_pub -h broker.hivemq.com -t 'testmqtt/demo/status' -r -nclient.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 Message | Persistente Session | |
|---|---|---|
| Geltungsbereich | Pro Topic, von allen Subscribern geteilt | Pro Client-ID |
| Was gespeichert wird | Nur die letzte Nachricht | Subscriptions plus jede verpasste QoS-1/2-Nachricht |
| Wer sie erhält | Jeder Client, der später abonniert | Nur dieser Client beim Reconnect |
| Typischer Einsatz | Aktueller Zustand | Keine 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:
| Feature | Was 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
- Publishe
onlinemit aktivierter Option Retain antestmqtt/your-id/status. - Trenne die Verbindung, verbinde dich neu und abonniere
testmqtt/your-id/#. Die Nachricht kommt sofort an, als Retained markiert. - 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.