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
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
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
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)