SubnetLayer

The Silly Window Syndrome

RFC 813 · how a correct connection talks itself into tiny, wasteful packets

Step 1 of 2 — understand the idea. Read this first and the packet trace will confirm what you already expect, instead of teaching you two things at once.

What you'll be able to do

Before this lesson — it builds directly on:
Every TCP segment costs 40 bytes of headers before any of your data goes in. That's fine when a segment carries 1460 bytes — the overhead is under 3%. It is catastrophic when a segment carries 1 byte. Silly window syndrome is a connection that talks itself into exactly that state and stays there: a receiver whose application reads slowly announces a tiny amount of free space, the sender dutifully fills it, the receiver reads a tiny amount more and announces another tiny space, forever. Neither side is misbehaving. The rules as originally written simply permitted a stable, terrible equilibrium.

✗ Common misunderstanding: The window field advertises how fast the link is.

Why that's wrong: It advertises free space in the receiver's buffer, in bytes. It says nothing about the network between the two hosts.

Correct model: Window = free memory at the receiver. Speed is a consequence (window ÷ round-trip time), not the meaning.

The packets prove it: In the sliding-window trace the window falls to 0 while the link is completely idle — the receiver's application simply stopped reading.

Watch these fields in the lab: tcp.windowSize

Picture the receiver's buffer as a shelf and the application as a shopper who takes tins off it. The sender is a delivery driver who refills whatever space is free. Normally the shopper takes a lot at once, a big space opens up, and the driver arrives with a full van. But if the shopper takes one tin at a time, the driver keeps making the entire journey to deliver one tin. The van, the fuel and the trip are the 40 bytes of headers; the tin is your 1 byte of data. The fix is on both ends: the shelf owner waits until there's real space before calling, and the driver waits until there's a worthwhile load before setting out.
A queue where everyone is scrupulously polite and nobody gets served
announcing every scrap of free space
the receiver advertising a tiny window
immediately filling it
the sender shipping a tiny segment
an equilibrium neither party chose
the syndrome itself

Where it breaks down: A queue resolves when somebody notices and changes their behaviour. Neither TCP endpoint can notice — each sees only correct local behaviour — which is why the cure had to be written into both sides of the protocol rather than left to judgement.

Buffers, the window, and bytes in flightThe sender holds data in a send buffer. Data that has been sent but not yet acknowledged is in flight. The receiver holds arrived data in a receive buffer until the application reads it, and advertises the remaining free space as the receive window.Sendersend buffer (queued to send)In flightsent, not yet acknowledgedReceiverarrived,unreadfreespaceadvertised window = free spaceRule: bytes in flight must never exceed the advertised window.App reads slowly → unread grows → window shrinks → sender must slow down.Window reaches 0 → sender stops completely until an update arrives.
The advertised window is FREE SPACE in the receiver's buffer — not bandwidth, not speed. It shrinks as data waits unread and reopens when the application reads.

Watch these fields in the lab: tcp.windowSize

✓ Concept check — before you open the packets

These test the idea, not the trace. You should be able to answer them from the explanation above.

Why does silly window syndrome need avoidance rules on BOTH the sender and the receiver?

Now that you understand the concept, observe how it appears in the packet exchange.

The lab runs a real simulated capture — pause, step, click any packet, and inspect every byte.