MQTT Keep Alive Interval Explained With Examples

mqtt-keep-aliveMQTT uses a TCP/IP connection.

This connection is normally left open by the client so that is can send and receive data at any time.

If no data flows over an open connection for a certain time period then the client will generate a PINGREQ and expect to receive a PINGRESP from the broker.

This message exchange confirms that the connection is open and working

This period is known as the keep alive period.

This is what the specification says:

The Keep Alive is a time interval measured in seconds. Expressed as a 16-bit word, it is the maximum 529 time interval that is permitted to elapse between the point at which the Client finishes transmitting one 530 Control Packet and the point it starts sending the next. It is the responsibility of the Client to ensure that 531 the interval between Control Packets being sent does not exceed the Keep Alive value. In the absence of 532 sending any other Control Packets, the Client MUST send a PINGREQ Packet [MQTT-3.1.2-23]. 533
The Client can send PINGREQ at any time, irrespective of the Keep Alive value, and use the PINGRESP 535 to determine that the network and the Server are working.

The default keep alive period for the Python MQTT client is 60 secs, but it can be set to anything you want when you establish the client connection.

The connect function can be called with 4 parameters as shown below :

connect(host, port=1883, keepalive=60, bind_address=””)

Note: When using the Python MQTT client you don’t normally need to generate these ping messages as they are taken care of by the client when you call the loop() function.

Viewing Client PINGREQ and PINGRESP Messages

You can view these ping requests and responses on the server and client.

To view on the server start mosquitto with the verbose option or enable logs- see Mosquitto logging and logs.

Here is a screen shot of the server console with retry period set to 20 seconds.


To view on the client use the on_log callback.

def on_log(client, userdata, level, buf):
    print("log: ",buf)

client.on_log=on_log # set client logging

The screen shot below shows the output of a client script that is connected to a broker, but doesn’t send or receive any messages.

You can see that the PINGREQ and PINGRESP messages.Here is a screen shot of the client.


You may think that sending messages on a regular basis would stop the PING messages but it turns out that the keep alive interval applies to both publish and receive messages.

Below is a screen shot with the client publishing at regular intervals( every 5 seconds) but pings are being sent (keep alive is 12 secs).


If I modify the test script by subscribing to the same topic so I receive messages, as well as publish messages, you notice that no PINGREQ and PINGRESP are being sent.


Failed Connections

In the absence of send and receive messages if for some reason the PING requests/responses aren’t successful then the broker will force disconnect the client.

I have modified the script to include a simple timer and set the keep alive to 6 seconds.

More importantly I have suppressed the PINGREQ message so the broker never sees it.

This is what the specification says should happen in these circumstances:

If the Keep Alive value is non-zero and the Server does not receive a Control Packet from the Client 538 within one and a half times the Keep Alive time period, it MUST disconnect the Network Connection to the 539 Client as if the network had failed [MQTT-3.1.2-24].

When I run the script this is what I see:


You can see that the server disconnects the client after approx 9 seconds.

Video- MQTT Keep Alives Explained

Common Questions and Answers

Q – Can I disable Keep alive messages?

A- Yes set the keep alive to 0

Q- Does it make sense to have a very long keep alive period?

A- Personally if I was expecting that a client would have very long periods (>15mins) of total inactivity I would disconnect it, and reconnect when It had data to send.

Related Tutorials and Resources





Please rate? And use Comments to let me know more
[Total: 10   Average: 4/5]


  1. Steve, thanks for this tutorial. One question, I was developing some mqtt projects with Arduino and the mqtt library, however I could not make the callback function to work with a gars interface. Now, the actual question is about the use of the ping messages to make sure the connection is up, or better said, to detect that the connection was down and has to be re-established (reconnect). is there any way to have feedback of the ping response not received so based on this to re-connect? thanks again.

  2. Hi Steve,

    My problem is that the last will is send by the broker but the client is not disconnected and accepts the next call. Probably a slow wifi connection. Problem is that subscribed clients think it is dead ( received last will ) but as the client does not need to reconnect it does not send a ‘connected’ (sent immediately after a connect) message.

    Keep alive = 15 seconds, issued by esp8266
    Server = mosquitto.

    Would the keepalive set to 30 seconds be better? I would like the value to be at least 2 pings further, but in the docs it says 1.5 times keep alive sends last will. Can i change the ping interval? Something like: pin every 20 seconds, keep alive 60 seconds. Thus 3 lost pings means we’re probable dead…


  3. Hi Steve,
    I am trying to teach my students the force disconnect state. Can you share how you were able to suppress the pinreq?

    1. Hi
      It’s been a while since I did it but I think that I commented out the line in the pingreq function in the module

      rc=self._send_simple_command(PINGREQ) but you need to set it as you will get an error on the next line
      def _send_pingreq(self):
      self._easy_log(MQTT_LOG_DEBUG, “Sending PINGREQ”)
      rc = self._send_simple_command(PINGREQ)
      if rc == MQTT_ERR_SUCCESS:
      self._ping_t = time_func()
      return rc

      def _send_pingresp(self):
      self._easy_log(MQTT_LOG_DEBUG, “Sending PINGRESP”)
      return self._send_simple_command(PINGRESP)


      1. Hi Steve,
        Thanks a lot. I was able to acheive similar result, by editing soucrrce code of Pubsubclient.cpp by nickoleary, for my esp32.

        Now i can simulate the condition for my students to learn

  4. hi can u tell me that when we use pingreq and we get pingres do value of keepalive reset and the connection will not brake

    1. The pingreq/response don’t stop the connection breaking but only detect a broken connection.
      Are you worried about the keepalive value?

  5. “…If for some reason the PING requests/responses aren’t successful then the broker will force disconnect the client.” — you mean AND if other control messages have not been received, right? That is, PINGREQ/PINGRESP messages are sent only in absence of other messages — if PUBLISH messages were regularly sent, there would be no need for PINGs at all.

    Also: “…. the keep alive interval applies to both publish and receive messages” — Do you mean: The same KeepAlive timer for PING[REQ|RESP] is set after after the client sends a PUBLISH message, after which a PINGREQ is sent? (not sure what you mean by RECEIVE; maybe you mean PUBREL when QoS=2?).

    1. Yes correct you only get ping messages if no other messages have been sent and received.
      By receive I mean that even if you have a client publishing messages continuously the Ping messages will be sent if the client isn’t receiving messages.

      I’ll amend the tutorial to make it clear

  6. Hi, will you going to make a youtube video for this tutorial? Also, can i ask for the test script you used to run this test?

Leave a Reply

Your email address will not be published. Required fields are marked *