한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Game Lag White Paper › L8 Sockets and protocols

Keepalive default of 2 hours TCP keepalive defaults

Cause ID sk-keepalive · Primary owner Game team (Server development) · Also Game team (Client development), Infra team (Server infrastructure)

Open the interactive card with figures and simulations →

When the other side vanishes without a close signal, TCP notices only much later. Keepalive (a TCP feature that checks whether an idle connection is still alive) is off by default, and even when it’s on, checks start only after 2 hours of idle time.

Why The client vanishes without a close signal because its power went off or its connection dropped → Effect The server assumes the connection is still alive (keepalive default 7,200 s; if data was being sent, about 15 minutes until retransmission gives up) → On screen A ghost character stays behind, and reconnecting fails with an “Already logged in” error

Symptoms
Can’t connect / infinite loading, Invisible / ghost entities
Factors
Packet loss
Who’s affected
Just me
When
After sitting idle, Right after login or maintenance
Owner
Primary owner Game team (Server development) · Also Game team (Client development), Infra team (Server infrastructure)
Game team action items
Server: answer heartbeats and close the connection yourself if nothing arrives for a set time (tune TCP_KEEPIDLE and TCP_USER_TIMEOUT), and on reconnect use the session token to replace the old session and resume it. Client: send game-level heartbeats every few seconds to tens of seconds (half the shortest idle timeout or less), reconnect automatically when disconnected.
Infra team action items
Lower the kernel defaults (tcp_keepalive_time and so on) for sockets whose code doesn’t set its own values (applies only to sockets with SO_KEEPALIVE on).
Ballpark numbers
By default, Linux starts checking after 7,200 seconds of idle time, sends 9 probes 75 seconds apart, and drops the connection if none are answered. That adds up to about 2 hours 11 minutes. Windows also waits for 2 hours of idle time by default before it starts checking.
On the graph
Outliers only · Time since last receive, per connection
Where to look
lastrcv (ms since the last receive) and the keepalive timer (timer:(keepalive,…)) per connection from ss -tnoi, lined up with the game server’s “Already logged in” rejections
Confirmed if
ESTABLISHED connections with lastrcv of minutes to hours are still there, and reconnects for those accounts are rejected with “Already logged in”
Ruled out if
No long-silent connections, yet “Already logged in” still appears: the game server’s session cleanup code
Check with
Infra tools (no game code needed)

Sources

  1. tcp(7) — Linux manual page Linux man-pages
    9 probes 75 s apart after 7,200 s of idle time (about 11 more minutes), applies only to sockets with SO_KEEPALIVE on, TCP_KEEPIDLE and TCP_USER_TIMEOUT
  2. RFC 9293: Transmission Control Protocol (TCP) IETF
    Keepalive must be off by default, and the default idle interval must be 2 hours or more
  3. SO_KEEPALIVE socket option Microsoft
    Default Windows TCP keepalive timeout: 2 hours
  4. ss(8) — Linux manual page iproute2
    lastrcv (ms since last receive) in -i, timer:(keepalive,…) in -o

See also

Same layer: L8 Sockets and protocols

Same symptom (Can’t connect / infinite loading), other layers

View the interactive card with figures and simulations