MQTT Keep Alive Timer to Keep Your Devices Connected
How many devices does your IoT system contain? The number can be small, up to five clients, or enormous with hundreds. For example, sensors, including magnetic contact sensors, power meters, chair occupancy sensors, etc. Regardless of the number of clients, it’s most likely that not all of them continuously transmit data. For example, if the temperature inside the fridge changes, a fridge’s sensor will send a message about this. For the rest of the time, this client remains ‘silent.’
If the clients remain silent for different reasons, an MQTT broker will disconnect them. At the same time, clients can ask the broker not to do this by notifying them that they are ‘alive.’ The MQTT Keep Alive parameter actually helps do this, and the intricacies we will cover in this article. So, let’s go!
What is MQTT Keep Alive, and why do you need it?
Keep Alive in MQTT is a flag that defines a time interval in seconds during which a client shall notify an MQTT broker that the connection is alive by sending a
PINGREQ message. If the client is not sending a message, the MQTT broker is getting attentive to it and disconnects the client after another half of the specified interval. The parameter can be specified in the variable header of an MQTT CONNECT request as follows:
In this example, the broker would start caring about the status after 300 seconds without communication between the client and the broker. It waits for the
PINGREQ message from the client. If the client is silent, the broker disconnects it after another 150 seconds. Likewise, if the broker does not respond to the client with the
PINGRESP message, the client shuts down the connection.
So, Keep Alive enables the broker to detect when the client drops off the so-called half-open connection.
Knowledge refresh: A half-open connection is a state of incomplete TCP connection when one part of the communication is not notified about the malfunction of the other part. As a result, it keeps sending messages waiting for an acknowledgment.
With the MQTT Keep Alive interval enabled, the MQTT broker will know the client’s status and keep it connected or cut off. Similarly, the client will be aware of any broker’s failure and close the connection, as it can detect the half-open connection also.
So, the primary value of the MQTT Keep Alive parameter is to detect disconnection between a broker and a client.
How MQTT Keep Alive works
We’ve already talked a lot about the value and some ins and outs of the MQTT Keep Alive parameter. However, the hands-on case can better illustrate the flow of this broker-client communication.
MQTT CONNECT request with KeepAlive
So, everything starts with an MQTT CONNECT request from a client to the broker. Here is what the CONNECT message with the Keep Alive header can look like:
clientID "client-1" cleanSession true username "cedalo" password "123" lastWillTopic "/fridge/door" lastWillQos 1 lastWillMessage "connection disabled" lastWillRetain false keepAlive 300
With the help of
keepAlive=300, the client told the MQTT broker that the Keep Alive interval is 300 seconds. Learn more about the other headers of the CONNECT request in our MQTT Connection Guide.
The connection is successfully established once the MQTT broker sends the CONNACK response with a 0 returnCode. After this, the parties start communicating with the help of PINGREQ and PINGRESP messages –
PINGREQ, that the client sends, being ‘I am still connected,’
PINGRESP: ‘Yes, me too.’
To learn more about MQTT Last Will parameters, check out this blog post.
MQTT Keep Alive messages
If the client is idle and does not send any MQTT PUBLISH or SUBSCRIBE messages, it notifies the broker that it’s alive with the help of
PINGREQ messages. The broker responds with
PINGRESP messages. The communication takes place according to the specified MQTT Keep Alive interval; this is every 300 seconds in our example. It’s okay if no messages are sent within the Keep Alive interval.
If the client sends an MQTT packet, for example, a PUBLISH message, the process of Keep Alive is cut and restored to the original status. Such a client is active and does not need to send
PINGREQ messages. The Keep Alive interval resets since, in fact, the message exchange has already taken place.
- PINGREQ Keep Alive message is the packet sent by the client to the MQTT broker according to the specified Keep Alive interval. A
PINGREQmessage tells that the client is alive and the connection is open.
- PINGRESP Keep Alive message is the packet sent by the MQTT broker to the client in response to its
MQTT client take-over after connection closed
keepalive equals 0, the connection will be closed if the MQTT broker does not receive any message from the client within the specified Keep Alive interval plus another half of the interval. In this case, the client will receive the LWT (last will and testament) message if the LWT was specified when establishing the connection. Likewise, the client closes the connection if the MQTT broker does not reply with a
PINGRESP message to the client’s
PINGREQ. However, in most cases, a disconnected client tries to reconnect.
Important: As the client sends any packet, the PINGREQ – PINGRESP exchange becomes obsolete, and the Keep Alive interval starts over at 0 seconds.
When the client is back online, and the previous connection is kept half-open, the broker performs a simple client take-over:
- It shuts down the previous connection to this client
- It establishes a new connection with this client.
MQTT Keep Alive FAQs
How long can the MQTT Keep Alive interval be?
The value for the
keepalive parameter is an integer representing time in seconds. For example,
keepalive=300 means that a client shall send a message, e.g., PUBLISH, to the MQTT broker every 300 seconds. After another 150 seconds, the broker closes the connection.
The maximum value for the Keep Alive interval is 65535, which is 18 hours, 12 minutes, and 15 seconds.
What is an MQTT Keep Alive default period?
keepalive interval is set to 15 seconds by default.
However, you can set any other Keep Alive interval up to 65535 when establishing the connection between a broker and a client.
MQTT Keep Alive interval equals zero
You can deactivate the MQTT Keep Alive mechanism if you use 0 as the interval:
Can the MQTT Keep Alive interval be different for broker and client?
Let’s assume that you use the Eclipse Mosquitto MQTT broker… or even the Pro Edition for Mosquitto, which is a better option for commercial projects. You can try the MQTT Broker sandbox in a free 14-day trial, so sign up!
So we assume that your MQTT broker’s default Keep Alive timeout is 10 seconds. Meanwhile, the client library you use is Arduino’s MQTT PubSubClient with 15 seconds as the default Keep Alive interval. Will this work?
The client determines the Keep Alive interval in the MQTT protocol when establishing a connection. So, in our example, the Mosquitto broker will use the client’s 15 seconds Keep Alive interval specified as a parameter in the CONNECT message.
However, for MQTT v.5.0 clients, there could also be a reverse way of setting an MQTT Keep Alive value – from the broker to the client. The broker can tell the client what Keep Alive interval it should use. The
max_keepalive option allows clients to connect with the Keep Alive interval less than or equal to the specified value. Unfortunately, there is no such mechanism for telling what Keep Alive interval to use for the MQTT v.3.1 and v.3.1.1 clients.
MQTT Keep Alive recap
Let’s wrap up this guide with a recap of the value provided by the Keep Alive parameter. It detects disconnected connections between the client and broker and discards these connections when they are no longer active.
The clients can remain idle for a specified interval, but then they must notify the broker that they are still alive with a PING request (
PINGREQ) message. This will let the MQTT broker keep them connected. If the client fails to send any message for any reason, it will be disconnected. Although, the broker can take the client over once it’s online. The PINGREQ-PINGRESP exchange becomes obsolete as the client sends any other packet while exchanging the
keepAlive messages. The
keepAlive interval starts counting again at zero seconds.
The Keep Alive functionality is quite useful for monitoring sensor connectivity. PING messages sent from sensors (clients) will let them stay connected even if they are inactive for some time. In addition, you could create sensor-specific rules to trigger alarms or other actions in case of communication failure.