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

Game Lag White Paper › L8 Sockets and protocols

Nagle’s algorithm + delayed ACK Nagle + delayed ACK (TCP_NODELAY off)

Cause ID sk-nagle · Primary owner Game team (Server development) · Also Game team (Client development)

Open the interactive card with figures and simulations →

Nagle’s algorithm, which batches small packets, and delayed ACK, which sends ACKs late, interact so that each message written in pieces is delayed by 40–200 ms.

Why Small messages are written in pieces without TCP_NODELAY turned on → Effect The sender waits for an ACK, and the receiver sends its ACK late → On screen Ping is low, yet every action is consistently sluggish: input lag

Symptoms
Input lag
Factors
Latency
Who’s affected
Whole server, Just me
When
Always, During specific actions
Owner
Primary owner Game team (Server development) · Also Game team (Client development)
Game team action items
Server: turn on TCP_NODELAY, collect one tick’s worth of messages and write them at once, don’t rely on turning off delayed ACK on the receiving side (Linux TCP_QUICKACK only lasts briefly, and Windows needs a registry change on every PC) because the game can’t reliably control it. Client: turn on TCP_NODELAY, collect one frame’s worth of messages and write them at once.
Ballpark numbers
Linux usually delays ACKs by 40 ms (up to 200 ms depending on the situation). Older Windows versions used 200 ms, and current versions use 40 ms (40 ms in the Windows Server 2019 default template). The receiving OS decides the delayed ACK, so if the server sends messages in pieces with Nagle on, each can be delayed by 40–200 ms depending on the receiving PC.
On the graph
Always high · Action response time (in-game RTT)
Where to look
Gaps between requests and responses in a server-side packet capture (tcpdump, Wireshark), and whether the server and client code turn on TCP_NODELAY
Confirmed if
Ping is low, but gaps of around 40 ms (200 ms on older Windows) keep appearing between small packets, and each gap ends right after the other side’s ACK arrives. Turning on TCP_NODELAY makes them disappear
Ruled out if
Response gaps close to ping: not this cause. Game server slow to produce responses: server processing (“Message queue backlog”)
Check with
Infra tools (no game code needed)

Sources

  1. RFC 9293: Transmission Control Protocol (TCP) IETF
    Nagle holds back small data while unacknowledged data is outstanding; it must be possible to turn off per connection; delayed ACK under 0.5 s; the problem of the two interacting
  2. include/net/tcp.h (Linux v6.12) Linux kernel
    Linux delayed ACK minimum TCP_DELACK_MIN (HZ/25 = 40 ms), maximum TCP_DELACK_MAX (HZ/5 = 200 ms)
  3. TCP improvements in the Windows network stack (IETF 98 TCPM) Microsoft
    Default delayed ACK timeout on Windows changed to 40 ms (announced in 2017)
  4. TCP Templates for Windows Server 2019 – How to tune your Windows Server Transports (Advanced users only 😉) Microsoft
    Server 2019 template: DelayedAckTimeout 40 ms, MaxSynRetransmissions 2, InitialRto 3000 ms
  5. Design issues - Sending small data segments over TCP with Winsock Microsoft
    Older Windows TCP starts a 200 ms delayed ACK timer when data arrives, and Nagle is on by default, so small packets wait for the ACK; fixed with TCP_NODELAY

See also

Same layer: L8 Sockets and protocols

Same symptom (Input lag), other layers

View the interactive card with figures and simulations