Fondamentaux MQTT

Intervalle keep alive MQTT : comment choisir la bonne valeur

L'intervalle keep alive détermine la vitesse à laquelle un broker remarque une connexion morte, ainsi que le trafic et la batterie que consomme un client inactif. Voici comment il fonctionne et comment choisir une valeur.

Illustration de l'intervalle keep alive MQTT montrant un appareil échangeant des paquets PINGREQ et PINGRESP avec un broker cloud sur une ligne de temps
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

L'intervalle keep alive MQTT est le nombre de secondes pendant lesquelles un client promet de ne jamais rester silencieux, et c'est le principal outil dont dispose un broker pour repérer les connexions mortes. Dans ce guide, vous verrez précisément comment fonctionnent PINGREQ, PINGRESP et la règle du timeout à 1,5x, comment le keep alive interagit avec les routeurs NAT, les liens cellulaires et l'autonomie de la batterie, et quelles valeurs choisir pour démarrer avec vos appareils.

Ce que fait réellement l'intervalle keep alive MQTT

Lorsqu'un client envoie un CONNECT, il y inclut un champ Keep Alive de deux octets exprimé en secondes. Cette valeur est un contrat : « je vous enverrai un paquet de contrôle au moins une fois sur cette période ». N'importe quel paquet compte, qu'il s'agisse d'un PUBLISH, d'un SUBSCRIBE ou d'un PUBACK. Ce n'est que lorsque le client n'a rien d'autre à envoyer qu'il se rabat sur un minuscule paquet PINGREQ, auquel le broker répond par un PINGRESP.

Le keep alive existe parce que TCP lui-même détecte mal les pairs morts. Si un appareil perd son alimentation ou si son modem cellulaire décroche du réseau, aucun paquet FIN ou RST n'est jamais envoyé. Le socket du broker reste « ouvert » indéfiniment de son point de vue, et tout subscriber qui attend le Last Will and Testament de l'appareil attend lui aussi indéfiniment. Le keep alive donne une échéance aux deux côtés.

La règle du timeout à 1,5x

La spécification MQTT indique que si le broker ne reçoit rien d'un client pendant une fois et demie l'intervalle de keep alive, il doit fermer la connexion réseau comme si elle avait échoué. Cela signifie :

Keep alive Le broker abandonne après Usage typique
15 s 22,5 s Tableaux de bord interactifs, basculement rapide
30 s 45 s Appareils sur secteur avec un Wi-Fi peu fiable
60 s 90 s Valeur par défaut raisonnable pour la plupart des appareils
120 s 180 s Appareils cellulaires attentifs à leur consommation de données
300 s 450 s Passerelles peu bavardes sur des liens stables
0 Jamais Keep alive désactivé (à éviter en production)

Le client a sa propre part du contrat. S'il envoie un PINGREQ et ne reçoit pas de PINGRESP dans un « délai raisonnable » (la plupart des bibliothèques utilisent la valeur du keep alive ou un timeout fixe), il doit considérer la connexion comme rompue et se reconnecter. C'est ainsi qu'un client découvre un socket à moitié ouvert de son côté.

Ce qui se passe quand le timeout se déclenche

Lorsque le broker ferme une connexion à cause du keep alive, il la traite comme une déconnexion anormale. Conséquences pratiques :

  1. Le message will du client est publié (après le will delay, si vous en avez défini un en MQTT 5 ; consultez le will delay interval MQTT).
  2. Si le client avait une session persistante, le broker conserve ses abonnements et commence à mettre en file d'attente les messages QoS 1 et QoS 2 qui lui sont destinés.
  3. Les topics de statut en ligne et les tableaux de bord passent à « hors ligne ».

Le keep alive contrôle donc directement la rapidité avec laquelle votre système apprend qu'un problème est survenu.

Choisir une valeur de keep alive MQTT

Il n'existe pas de valeur universellement correcte. Vous arbitrez entre vitesse de détection d'une part, trafic et consommation d'énergie d'autre part.

Vitesse de détection

Un intervalle plus court permet au broker et aux subscribers d'apprendre plus vite les pannes. Si un tableau de bord d'exploitation doit afficher une machine hors ligne en moins d'une demi-minute, un keep alive de 60 secondes (détection à 90 secondes) ne répondra pas à cette exigence, alors que 15 ou 20 secondes conviendront.

Timeouts d'inactivité des NAT et pare-feu

C'est le piège dans lequel tombent la plupart des équipes. Les box domestiques, les pare-feu d'entreprise, les load balancers cloud et surtout les passerelles NAT des opérateurs mobiles suppriment les translations TCP restées inactives pendant un certain temps. Une fois la translation supprimée, le paquet suivant du client ne va nulle part, et le broker ne s'en aperçoit qu'à l'échéance des 1,5x. Si votre keep alive est plus long que le plus court timeout d'inactivité NAT sur le chemin, vous subissez des déconnexions mystérieuses toutes les quelques minutes. Les timeouts NAT des opérateurs varient beaucoup et ne sont pas toujours documentés : sur les liens cellulaires, il est donc plus sûr de rester nettement sous quelques minutes.

Batterie et consommation de données

Chaque aller-retour PINGREQ/PINGRESP ne représente que 2 octets de payload MQTT dans chaque sens, plus le surcoût TCP/IP (et des enregistrements TLS). En Wi-Fi, c'est négligeable. Sur un appareil cellulaire sur batterie, le coût tient surtout aux réveils de la radio, pas aux octets : chaque ping peut maintenir le modem dans un état de forte consommation pendant plusieurs secondes. Pour ces appareils, demandez-vous si une connexion permanente est vraiment nécessaire, ou s'il vaut mieux se réveiller, publier et se déconnecter avec une session persistante.

Un point de départ pratique

  • Appareils sur secteur en Wi-Fi ou Ethernet : 60 secondes.
  • Tableaux de bord et clients navigateur en WebSocket : 30 secondes.
  • Passerelles cellulaires : 60 à 120 secondes, puis réduisez si vous constatez des coupures inexpliquées.
  • Services backend dans la même région cloud : 30 à 60 secondes.
  • N'utilisez jamais 0 en production : cela supprime totalement la détection des connexions mortes.

Définir l'intervalle keep alive dans les clients courants

Vous pouvez tester tous ces exemples sur le serveur MQTT public gratuit broker.connectmq.com, réservé aux tests et aux prototypes. Utilisez un client ID unique et un préfixe de topic unique, et n'oubliez pas que l'espace public est lisible par tous.

mosquitto_sub et mosquitto_pub

# S'abonner avec un keep alive de 30 secondes et la sortie de débogage pour voir PINGREQ/PINGRESP
mosquitto_sub -h broker.connectmq.com -p 1883 -i ka-demo-7f3a \
  -k 30 -d -t 'connectmq/demo/7f3a/#'

Avec -d, vous verrez des lignes comme Client ka-demo-7f3a sending PINGREQ et received PINGRESP toutes les 30 secondes tant que le topic reste calme.

Python (paho-mqtt 2.x)

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe("connectmq/demo/7f3a/#", qos=1)

def on_disconnect(client, userdata, flags, reason_code, properties):
    print("Disconnected:", reason_code)

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id="ka-python-7f3a",
    protocol=mqtt.MQTTv5,
)
client.on_connect = on_connect
client.on_disconnect = on_disconnect

# keepalive est le troisième argument, en secondes
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()

paho envoie automatiquement les PINGREQ depuis sa boucle réseau. Si vous bloquez la boucle (par exemple avec un long time.sleep dans un callback), les pings s'arrêtent et le broker vous déconnectera après 1,5x l'intervalle.

Node.js (MQTT.js v5)

const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "ka-node-7f3a",
  protocolVersion: 5,
  keepalive: 45,          // secondes
  reconnectPeriod: 5000,  // ms entre les tentatives de reconnexion
});

client.on("connect", () => console.log("connected"));
client.on("close", () => console.log("connection closed"));
client.on("error", (err) => console.error(err.message));

ESP32 (PubSubClient)

PubSubClient utilise 15 secondes par défaut. Modifiez la valeur avant d'appeler connect() avec client.setKeepAlive(60);, et veillez à ce que client.loop() s'exécute fréquemment dans votre sketch, car les pings ne sont envoyés que depuis loop(). Les longs appels à delay() sont la raison la plus fréquente pour laquelle les cartes ESP32 décrochent à intervalles réguliers. Un sketch ESP32 bien structuré utilise une boucle non bloquante avec des minuteries millis() pour l'éviter.

Server Keep Alive en MQTT 5

MQTT 5 permet au broker de passer outre la demande du client. Si le CONNACK contient une propriété Server Keep Alive, le client doit utiliser cette valeur au lieu de la sienne. Les brokers le font pour imposer un intervalle minimum ou maximum sur une plateforme partagée. La plupart des bibliothèques l'appliquent silencieusement : si vous constatez des pings à un rythme différent de celui que vous avez configuré, journalisez les propriétés du CONNACK. Dans paho, vous pouvez afficher properties dans on_connect ; MQTT.js les expose sur le paquet connack transmis à l'événement connect.

Dépanner les problèmes de keep alive

Utilisez cette check-list lorsque des clients se déconnectent à des intervalles étrangement réguliers :

  1. Mesurez l'écart. Si les déconnexions surviennent environ 1,5x votre keep alive après la dernière activité, le client n'envoie pas de pings. Cherchez une boucle réseau bloquée.
  2. Recherchez une coupure d'inactivité fixe. Si les coupures surviennent après un nombre constant de minutes quel que soit le keep alive, un NAT ou un pare-feu arrive en timeout. Abaissez l'intervalle sous cette valeur.
  3. Recherchez des client ID en double. Deux clients avec le même ID s'éjectent mutuellement, ce qui ressemble à un problème de keep alive sans en être un. Consultez les bonnes pratiques pour le client ID MQTT.
  4. Méfiez-vous des callbacks monothread. Un traitement lourd dans on_message retarde le PINGREQ. Déplacez le traitement vers un thread de travail ou une file d'attente.
  5. Vérifiez que les poignées de main TLS aboutissent. Sur les appareils contraints, une reconnexion TLS lente peut repousser le ping suivant au-delà de l'échéance.
  6. Activez la journalisation de débogage de votre bibliothèque et comparez les horodatages du client avec les événements de connexion du broker.

Sur un broker ConnectMQ, vous pouvez aussi surveiller $SYS/broker/connection/{clientId}/state pour voir précisément quand le broker considère un client comme connecté ou déconnecté, ce qui facilite la corrélation avec les journaux de vos appareils. Le client MQTT intégré au navigateur du portail permet de s'abonner rapidement à ce topic sans rien installer.

Keep alive, sessions et Last Will travaillent ensemble

Le keep alive n'est qu'une pièce d'une conception plus large de la fiabilité. Un modèle de production raisonnable ressemble à ceci :

  • Un keep alive assez court pour devancer les timeouts NAT et atteindre votre objectif de détection.
  • Un message « online » retenu publié à la connexion, plus un message will « offline » retenu.
  • Une session persistante pour que les messages QoS 1 publiés pendant la reconnexion de l'appareil ne soient pas perdus.
  • Un backoff exponentiel à la reconnexion, pour qu'un redémarrage du broker ne se transforme pas en ruée simultanée.

Le tutoriel MQTT couvre ces briques depuis le début si vous souhaitez le contexte plus large.

Démarrer avec ConnectMQ

ConnectMQ est un broker MQTT managé qui prend en charge MQTT 3.1.1 et 5.0 en TCP, TLS, WebSocket et WebSocket sécurisé : vous pouvez donc tester n'importe quelle stratégie de keep alive sur les mêmes endpoints que ceux que vous utiliserez en production. Lorsque vous êtes prêt à dépasser le serveur MQTT public gratuit, créez un broker Serverless gratuit sans carte bancaire, copiez les identifiants générés et suivez l'état des connexions en direct dans le portail. Si vous comparez encore les options, notre guide pour choisir un broker MQTT cloud passe en revue les compromis.

Questions fréquentes

Quel est un bon intervalle keep alive MQTT par défaut ?

60 secondes est une bonne valeur par défaut pour la plupart des appareils sur secteur. Réduisez-la à 15 à 30 secondes si vous avez besoin d'une détection hors ligne plus rapide, ou si un équipement NAT sur le chemin coupe plus tôt les connexions inactives.

N'importe quel paquet MQTT réinitialise-t-il le minuteur keep alive ?

Oui. Tout paquet de contrôle envoyé par le client, y compris PUBLISH et PUBACK, compte comme une activité. Le PINGREQ n'est envoyé que lorsque le client est resté inactif pendant tout l'intervalle.

Que se passe-t-il si je règle le keep alive sur 0 ?

Le keep alive est désactivé : le broker ne ferme donc jamais de lui-même une connexion silencieuse. Des appareils morts peuvent sembler connectés indéfiniment et leurs messages will ne jamais être envoyés : évitez 0 en production.

Pourquoi mon client se déconnecte-t-il exactement toutes les quelques minutes ?

Un intervalle constant quel que soit votre réglage de keep alive indique généralement un timeout d'inactivité NAT ou pare-feu. Réglez le keep alive sous ce timeout pour que les pings maintiennent la translation active.

Le broker peut-il modifier ma valeur de keep alive ?

En MQTT 5, oui. Le broker peut renvoyer une propriété Server Keep Alive dans le CONNACK, et le client doit utiliser cette valeur au lieu de celle qu'il a demandée.

Articles liés

Qui a inventé MQTT ? L'histoire, des oléoducs à l'IoT

MQTT a été inventé en 1999 par Andy Stanford-Clark (IBM) et Arlen Nipper (Arcom) pour surveiller des oléoducs par satellite. Suivez son parcours vers l'open source, OASIS, l'ISO et les brokers MQTT managés d'aujourd'hui.

8 min de lecture

Pourquoi votre client MQTT se déconnecte sans cesse (et comment y remédier)

Les boucles de reconnexion sont l'un des problèmes MQTT les plus courants. Découvrez les cinq causes habituelles, des client ID en double aux timeouts de keep alive et aux paquets trop volumineux, et suivez une méthode de diagnostic qui identifie la vôtre.

9 min de lecture

Taille maximale d'un message MQTT : limites et stratégies pour les gros payloads

MQTT peut techniquement transporter un paquet de 256 Mo, mais les brokers, les bibliothèques clientes et les appareils imposent des limites bien plus basses. Découvrez où se trouvent les vraies limites, ce qui se passe quand on les dépasse et comment envoyer de gros payloads.

8 min de lecture

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.