Votre pool de connexions PostgreSQL renvoie soudain « server closed the connection unexpectedly ». Votre client WebSocket se reconnecte toutes les dix minutes. Votre API gRPC fonctionne en local, mais en production derrière un load balancer les streams longs se coupent sans log applicatif.
Le coupable n'est pas toujours un bug de code. Souvent, un équipement intermédiaire a tué une session TCP idle, et personne ne l'a remarqué — jusqu'au prochain write.
Idle timeout : qui coupe, et quand
| Couche | Timeout idle typique | Conséquence |
|---|---|---|
| NAT box / 4G | 30 s – 5 min | Connexion « zombie » côté app |
| Load balancer cloud | 60 s – 3500 s | Coupure silencieuse mid-request |
| Firewall stateful | Variable | Drop sans RST propre |
| Serveur DB | heures | Moins fréquent en défaut |
Sans trafic, la session disparaît de la table de state de l'intermédiaire. Votre processus croit encore être connecté.
Le keepalive existe pour détecter tôt que le chemin est mort — pas pour remplacer une architecture qui maintient du trafic utile.
TCP keepalive au niveau noyau
Linux envoie des probes TCP vides après une période d'inactivité (tcp_keepalive_time, défaut ~7200 s — souvent trop long pour le web).
Paramètres utiles :
sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=5
Activez SO_KEEPALIVE sur les sockets serveur critiques (PostgreSQL tcp_keepalives_*, Redis, proxies).
Limite : le keepalive ne traverse pas toujours les proxies HTTP qui terminent TCP. Derrière nginx, réglez aussi proxy_read_timeout et proxy_send_timeout.
Heartbeat applicatif : quand le TCP ne suffit pas
Pour WebSocket, SSE ou connexions DB via pooler :
- WebSocket : ping/pong RFC 6455 ou message JSON périodique (< intervalle NAT).
- Pools ORM :
pool_pre_ping(SQLAlchemy), validation query au checkout. - Message queues : heartbeat AMQP, consumer ack régulier.
Calibrez l'intervalle sous le timeout le plus court de la chaîne (NAT < LB < app).
Load balancer et hébergeur cloud
Les offres managées exposent des timeouts fixes :
- AWS ALB idle : jusqu'à 4000 s configurable.
- nginx par défaut : 60 s sur proxy.
- Cloudflare : 100 s sur connexions HTTP classiques.
Lisez la doc de votre couche — puis réglez keepalive + heartbeat en conséquence. Ouvrir un ticket support hébergeur si le timeout par défaut est incompatible avec vos flux longs.
Le sommet : une connexion « ouverte » peut déjà être morte
La robustesse finale reste dans votre code de retry et de reconnexion.
Décider et avancer sans angle mort
- Cartographiez les timeouts de NAT, LB, proxy et DB sur un schéma.
- Activez SO_KEEPALIVE + paramètres sysctl adaptés sur les serveurs.
- Ajoutez heartbeat applicatif pour WebSocket et pools longue durée.
- Testez en charge avec connexions idle délibérées.
Comparez les hébergeurs et leurs limites réseau dans notre annuaire.
Questions fréquentes
Quelle différence entre TCP keepalive et heartbeat applicatif ?
Keepalive = probes noyau pour détecter un pair mort. Heartbeat = message métier qui peut aussi mesurer latence ou rafraîchir une session.
Pourquoi mes connexions DB tombent après 5 ou 15 minutes ?
NAT, firewall ou load balancer ferme les sessions idle ; le client croit la connexion ouverte.
Quels paramètres Linux ajuster ?
tcp_keepalive_time, tcp_keepalive_intvl, tcp_keepalive_probes — baissez time si timeouts intermédiaires courts.
Le keepalive consomme-t-il beaucoup de bande passante ?
Non — quelques octets par probe ; évitez un intervalle trop agressif sur des milliers de connexions.
Une connexion utile n'est pas celle qui reste ouverte dans un tableau — c'est celle qui survit aux NAT silencieux entre deux requêtes réelles.
