Independent comparison · no paid rankings
Home / Blog / Technical / TCP keepalive: retain useful connections without letting them die

TCP keepalive: retain useful connections without letting them die

Long-lived connections die silently when a NAT or load balancer cuts idle flows. TCP keepalive detects that — provided you do not confuse it with application heartbeats.

Hébergeurs.eu Editorial Team 3 min read

Your PostgreSQL connection pool suddenly returns "server closed the connection unexpectedly". Your WebSocket client reconnects every ten minutes. Your gRPC API works locally, but in production behind a load balancer long streams drop with no application log.

The culprit is not always a code bug. Often an intermediate device killed an idle TCP session, and nobody noticed — until the next write.

Idle timeout: who cuts, and when

LayerTypical idle timeoutConsequence
NAT box / 4G30 s – 5 min"Zombie" connection on app side
Cloud load balancer60 s – 3500 sSilent mid-stream cut
Stateful firewallVariableDrop without clean RST
DB serverhoursLess common by default

With no traffic, the session vanishes from the intermediary state table. Your process still believes it is connected.

Keepalive exists to detect early that the path is dead — not to replace an architecture that maintains useful traffic.

Kernel-level TCP keepalive

Linux sends empty TCP probes after idle time (tcp_keepalive_time, default ~7200 s — often too long for the web).

Useful settings:


sysctl -w net.ipv4.tcp_keepalive_time=600

sysctl -w net.ipv4.tcp_keepalive_intvl=30

sysctl -w net.ipv4.tcp_keepalive_probes=5

Enable SO_KEEPALIVE on critical server sockets (PostgreSQL tcp_keepalives_*, Redis, proxies).

Limit: keepalive does not always survive HTTP proxies that terminate TCP. Behind nginx, also set proxy_read_timeout and proxy_send_timeout.

Application heartbeat: when TCP is not enough

For WebSocket, SSE or DB connections via pooler:

  • WebSocket: RFC 6455 ping/pong or periodic JSON (< NAT interval).
  • ORM pools: pool_pre_ping (SQLAlchemy), validation query on checkout.
  • Message queues: AMQP heartbeat, regular consumer ack.

Calibrate interval below the shortest timeout in the chain (NAT < LB < app).

Load balancer and cloud host

Managed offerings expose fixed timeouts:

  • AWS ALB idle: up to 4000 s configurable.
  • nginx default: 60 s on proxy.
  • Cloudflare: 100 s on classic HTTP connections.

Read your layer's docs — then tune keepalive + heartbeat accordingly. Open a host support ticket if default timeout conflicts with long flows.

The climax: an "open" connection may already be dead

Final robustness lives in your retry and reconnection logic.

Decide and move forward without blind spots

  1. Map timeouts for NAT, LB, proxy and DB on one diagram.
  2. Enable SO_KEEPALIVE + adapted sysctl on servers.
  3. Add application heartbeat for WebSocket and long-lived pools.
  4. Load-test with deliberate idle connections.

Compare hosts and network limits in our directory.

Frequently asked questions

What is the difference between TCP keepalive and application heartbeat?

Keepalive = kernel probes for dead peer. Heartbeat = business message that can also measure latency or refresh sessions.

Why do DB connections drop after 5 or 15 minutes?

NAT, firewall or load balancer closes idle sessions; client thinks connection is open.

Which Linux parameters to tune?

tcp_keepalive_time, tcp_keepalive_intvl, tcp_keepalive_probes — lower time for short intermediary timeouts.

Does keepalive use a lot of bandwidth?

No — a few bytes per probe; avoid aggressive intervals on thousands of connections.


A useful connection is not one that stays open in a table — it is one that survives silent NATs between real requests.

Compare European hosts

Filter by compliance, location and use case — then open the sheets to verify the real scope.

Browse the directory
Blog

Related reading

All articles →