MQTT/Staying connected/Keepalive

Keepalive

An MQTT connection stays open for days, and the broker cannot see down it. So an idle device checks in every keepalive interval, and the broker hangs up after one and a half intervals of silence.

A device connects to the broker once and then stays connected, for hours or weeks, posting and receiving on the same connection. That is much of why MQTT is light: the handshake happens once, not for every message.

But a connection that is open on paper can be dead in practice. The device lost power, the Wi-Fi went, a router in between forgot about it. Neither end is told.

Checking in

When a device connects it tells the broker its keepalive, a number of seconds. If it has sent nothing else for that long, it sends a small PINGREQ, and the broker answers PINGRESP. Anything the device sends counts, so a sensor posting every five seconds with a keepalive of fifteen never needs to ping at all.

If the broker hears nothing for one and a half keepalives, it decides the device has gone and closes the connection. With the Arduino PubSubClient library's default keepalive of 15 seconds, that is 22.5 seconds.

A round station clock over a post-office counter, its second hand blurred
The broker's clock runs from the last time it heard from the device.Generated illustration

client.loop()

In an Arduino sketch the pings, and everything else coming in, are handled by client.loop(). It has to run often: every time round loop(), with nothing in the sketch that blocks for longer than the keepalive. A sketch that waits in a delay(60000) is a device that stopped checking in.

The trap is that the device is the last to know. The broker has closed the connection; the sketch carries on posting, and nothing in it notices unless it checks what publish() returns, or calls client.connected().

Choosing a number

A longer keepalive means fewer pings, which matters on a battery or a metered link, and a longer wait before anybody notices a device has died. Fifteen to sixty seconds is usual on a home network. What the broker does once it notices is the next lesson.

Common mistakes

  • A long delay() in loop(). Use millis() to post every so often, and let loop() run.
  • Posting without checking client.connected(). Reconnect first, then post.
  • A keepalive of 0. It turns the check off: the broker never notices the device has gone.

Edit this page — content/fundamentals/mqtt/keepalive.mdx

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Fundamentals on the forum →