What is the TCP sliding window, and how is flow control different from congestion control?
Show the answer
Say this first
The receiver advertises a receive window in every segment: how many more bytes it has buffer space for. The sender may have at most the smaller of that receive window and its own congestion window sent but not yet acknowledged. As ACKs arrive the window slides forward and more data can go. Flow control protects the receiver and is driven by the receiver's advertised window. Congestion control protects the network and is the sender's private estimate, the congestion window, which never appears in a packet.
Go deeper
The picture
bytes: | acked | sent, not acked | can send now | cannot send yet |
^ SND.UNA ^ SND.NXT ^ SND.UNA + windowUsable window = min(rwnd, cwnd) minus bytes in flight. When the receiver's application reads data, the receiver advertises a bigger window. When the sender gets ACKs, SND.UNA moves right.
Why it bounds throughput
A sender can put at most one window of data on the wire per round trip, so one flow's throughput is at most window / RTT. That single formula explains most "fast link, slow transfer" tickets.
Who sets what
| Control | Variable | Set by | Visible in packets |
|---|---|---|---|
| Flow control | rwnd | Receiver, from free buffer | Yes, Window field |
| Congestion control | cwnd | Sender's algorithm | No |
They will ask next
How do you see the congestion window if it is never on the wire?
On the sender:
ss -tishowscwnd:in segments along withrtt:andssthresh:. In Wireshark you estimate it from "bytes in flight" in the TCP analysis on a capture taken near the sender.What limits a single TCP flow's throughput?
The smallest of: receive window / RTT, congestion window / RTT, the sender's socket buffer, the bottleneck link, and the application's own speed reading or writing.
Traps
- Saying the window is counted in segments. The advertised window is in bytes (after scaling).