Fundamentals

MQTT Retained Messages: How They Work and How to Clear Them

MQTT retained messages explained: how the retain flag works, when to use it, how to clear a retained message with an empty payload, and MQTT 5 retain options.

Updated · 6 min read

Normally an MQTT broker forwards a message to the clients that are subscribed right now and then forgets it. A client that subscribes a minute later sees nothing until the next publish. Retained messages solve this: the broker stores the last retained message for a topic and hands it to every new subscriber immediately, so they always start with the current state.

How retained messages work

Retention is controlled by a single bit, the RETAIN flag in the PUBLISH packet. When the broker receives a publish with RETAIN=1:

  1. It delivers the message to current subscribers, as usual.
  2. It stores the message (topic, payload, QoS) as the retained message for that topic, replacing any previous one. There is at most one retained message per topic.
  3. Whenever a client later subscribes with a filter that matches the topic, the broker sends the retained message right after the SUBACK, with the retain flag set so the client knows it is a stored value.
Retained message timeline
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 receive the retained messages of every matching topic, which is how a dashboard that subscribes to acme/+/status can paint the state of all devices on startup.

The retain flag on delivery

In MQTT 3.1.1, a message forwarded to an existing subscriber always has the retain flag cleared; the flag is only set when the message is sent because of a new subscription. MQTT 5 keeps that default but adds the Retain As Published subscription option, which preserves the original flag — useful for bridges.

Without retention, a newly started dashboard would show empty tiles until every device happened to publish again — which for a door sensor or a configuration value could take hours. With retention, the first screen is already correct.

When to use retained messages

  • Device state — online/offline, on/off, current mode.
  • Configuration and setpoints — a device that reboots subscribes and immediately gets its config.
  • Slow-changing values — firmware version, location, last known reading.
  • Presence together with a retained Last Will message, so the offline status sticks.

Avoid retaining:

  • Events and commands — a retained unlock-door command would be replayed to every new subscriber, possibly days later.
  • High-frequency streams — retaining is harmless but pointless when the next value arrives in a second.
  • Per-message topics — topics containing IDs or timestamps leave thousands of stale retained messages behind.

How to clear a retained message

To delete a retained message, publish to the same topic with the retain flag set and a zero-length payload. The broker removes the stored message and does not store the empty one. Current subscribers do receive the empty message, so make your code ignore empty payloads.

Clear a retained message with mosquitto_pub
# -r = retain, -n = send a null (zero-length) payload
mosquitto_pub -h broker.hivemq.com -t 'testmqtt/demo/status' -r -n
Clear a retained message with MQTT.js
client.publish('testmqtt/demo/status', '', { retain: true, qos: 1 });

To clear many topics at once, subscribe with a wildcard, collect every topic that delivers a message with the retain flag, and publish an empty retained payload to each. There is no standard "delete all retained" command — some brokers offer admin tools, but they are broker-specific.

Retained messages vs persistent sessions

Retained messages are often confused with persistent sessions, but they answer different questions:

Retained messagePersistent session
ScopePer topic, shared by all subscribersPer client ID
What is keptOnly the latest messageSubscriptions plus every missed QoS 1/2 message
Who receives itAny client that subscribes laterOnly that client when it reconnects
Typical useCurrent stateNot missing events

A device that needs both its current configuration and every command sent while it was offline uses both: a retained config topic and a persistent session for the command topic. The QoS guide explains how sessions and QoS interact.

Retained messages also keep their QoS. When the broker delivers a stored message to a new subscriber, the usual downgrade rule applies: the subscriber receives it at the lower of the original QoS and its subscription QoS.

Retained messages in MQTT 5

MQTT 5 adds finer control over retained messages:

FeatureWhat it does
Retain Handling (subscription option)0 = send retained messages on subscribe (default), 1 = only if the subscription is new, 2 = never send them
Retain As Published (subscription option)Keeps the original retain flag on forwarded messages
Message Expiry Interval (publish property)The broker discards the retained message after the given number of seconds
Retain Available (CONNACK property)Tells the client whether the broker supports retained messages at all

Message expiry is especially handy: a retained sensor reading that expires after an hour can never be mistaken for a fresh one. See MQTT 5 vs 3.1.1 for the full list of changes.

Test retained messages

  1. Publish online with Retain checked to testmqtt/your-id/status.
  2. Disconnect, reconnect and subscribe to testmqtt/your-id/#. The message arrives instantly, marked as retained.
  3. Publish an empty payload with Retain checked, resubscribe — nothing arrives. The retained message is gone.

Try it in the online MQTT client

The online MQTT client shows a retained badge on stored messages, which makes stale state easy to spot. For a broader checklist, see how to test an MQTT broker.

Frequently asked questions

How do I delete a retained message in MQTT?

Publish a message with the retain flag set and a zero-length (empty) payload to the same topic. The broker removes the stored retained message, and the empty message is not kept. With mosquitto_pub use -r -n.

How many retained messages can a topic have?

One. The broker keeps only the most recent retained message per topic; each new retained publish replaces the previous one.

Is a retained message the same as a persistent session?

No. A retained message is the last value of a topic, delivered to any new subscriber. A persistent session queues messages for one specific client while it is offline. They solve different problems and are often used together.