Skip to content
Stand with Ukraine flag

Sessions

A session is the state TBMQ keeps on behalf of one client, identified by its client ID: the subscriptions it holds, the QoS 1 and QoS 2 messages still being acknowledged in either direction, and — while the client is away — the messages that arrived for it in the meantime. Whether that state outlives the network connection is the most consequential thing a client declares in its CONNECT packet.

A persistent session survives a disconnect, so the client resumes its subscriptions and collects what it missed. A non-persistent (clean) session lasts only as long as the connection: it costs the broker nothing in between, and anything published while the client is away is lost to it. For a protocol-level introduction, see the MQTT persistent session guide.

The client decides, and the flags differ by protocol version:

MQTT version Non-persistent Persistent
3.1.1 Clean Session = 1 Clean Session = 0
5.0 Clean Start = 1 and Session Expiry Interval = 0 (or unset) Session Expiry Interval > 0 (whatever Clean Start says), or Clean Start = 0 with Session Expiry Interval = 0

Two consequences are worth internalizing. Because the state is stored under the client ID, a persistent session needs a stable one — a client that reconnects with a different identifier gets a new session, not its old one. And because the state belongs to the identifier rather than to the connection, the broker tells a reconnecting client through the Session Present flag in CONNACK whether it resumed an existing session or was given a fresh one, which is how a client knows whether it still has to subscribe.

An MQTT 5.0 client requests a lifetime with the Session Expiry Interval, but does not have the last word: TBMQ caps the value at a server maximum — one week by default — enforces the capped value, and returns it in CONNACK. Sessions that by protocol rules would never expire at all (MQTT 3.1.1 Clean Session = 0, or MQTT 5.0 Clean Start = 0 with no expiry interval) are subject to an administrative TTL instead, also one week by default, so abandoned state cannot accumulate indefinitely. Both limits are configurable, and the housekeeping that applies them runs on a schedule rather than at the exact instant a session expires.

Persistence is storage, and where it lives depends on the client type — the DEVICE and APPLICATION paths are built for very different volumes. Only QoS 1 and QoS 2 messages are ever queued for an offline client, and only when both publisher and subscriber use them; see Delivery guarantees.

Use a persistent session when a client must not miss messages across the outages it will inevitably have: a device on a cellular link, a backend consumer that has to see every event. Use a clean session for anything that subscribes afresh on connect and has no use for stale data — a dashboard, a test client, a short-lived tool.

Sessions of both kinds, connected and disconnected, are listed on the Sessions page of the UI, where you can inspect a session’s subscriptions or clear it. See Non-persistent and persistent sessions for the complete session state, the expiry parameters and a worked example, and Sessions for the UI.