Stopping Tinygrams: Silly Window Syndrome and Nagle's Algorithm
Every TCP/IP packet incurs a mandatory protocol header overhead:
- IPv4 Header: 20 bytes (minimum)
- TCP Header: 20 bytes (minimum)
- Total Overhead: 40 bytes
When an interactive application transmits small data chunks (such as single keystrokes over Telnet or SSH), transmitting 1 byte of user data inside a 41-byte datagram results in an appalling 4,000% header overhead.
Left unchecked, this dynamic triggers Silly Window Syndrome (SWS), choking high-speed networks under waves of tinygrams.
1. Silly Window Syndrome: The Receiver's Role
Silly Window Syndrome occurs when:
- The receiving application consumes data slowly (e.g., calling
read()for 1 byte at a time). - The receiver advertises an updated Receive Window (
rwnd) of 1 byte. - The sender immediately transmits a 1-byte segment.
- The cycle repeats continuously, locking the connection into 1-byte transmissions.
Clark's Receiver Solution:
To prevent receiver-driven SWS, Clark's Algorithm instructs the receiver to refuse advertising tiny windows:
- The receiver advertises
rwnd = 0until it can accommodate:
Free Space ≥ min(MSS, (Buffer Size / 2))
Once this threshold is reached, the receiver opens the window with a large update.
2. Nagle's Algorithm: The Sender's Role
Published in RFC 896 by John Nagle, Nagle's Algorithm prevents the sender from emitting tinygrams:
if there is new data to send:
if the window size >= MSS and available data >= MSS:
send complete MSS segment immediately
else:
if there is unconfirmed data in flight (waiting for ACK):
buffer data in memory until previous ACK arrives
else:
send the data immediately
Key Intuition:
- The sender sends the first packet immediately (ensuring zero latency for initial writes).
- While waiting for the roundtrip ACK, subsequent small writes are automatically coalesced into a single larger buffer.
3. The Modern Gotcha: Nagle vs Delayed ACK
Modern operating systems enable Delayed ACKs (waiting 40ms–200ms before sending an ACK to piggyback on return data).
When Nagle's Algorithm (waiting for an ACK) meets Delayed ACKs (waiting for data to send an ACK), the connection deadlocks in a 200ms latency pause!
- Fix: For interactive applications, real-time gaming, and microservices (gRPC), disable Nagle's algorithm by setting the socket option:
int flag = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
Explore full TCP transport architectures at Binary Dose.
Top comments (0)