102005101520cwnd (segments)round tripsyouothercwnd–cwnd14
Cells: the congestion window, one per segment in flightOrange blocks: packets waiting in the router's queueThin pipe: the bottleneck linkBoard: cwnd per round trip; × marks a lossTwo senders share one router whose outgoing link carries 20 packets per round trip, with a 10-packet queue. Neither knows those numbers, so TCP probes: slow start doubles the congestion window each round trip, a full queue drops packets, the window is halved, then it grows by one segment per round trip. The cells in front of each laptop are its cwnd; the board plots both windows over 22 round trips. 192.0.2.10, 198.51.100.7 and 203.0.113.10 are RFC 5737 documentation addresses.

The bottleneck

  1. Your laptop and another sender both upload to a server through one router. The router's outgoing link is the bottleneck: it carries only 20 packets per round trip. Neither sender knows that number.

Slow start

Loss

Sharing the pipe

The numbers, round trip by round trip

;; step 1/10 · bottleneck · round trips 0
you    192.0.2.10  → 203.0.113.10
other  198.51.100.7 → 203.0.113.10
bottleneck link  20 packets per round trip (illustrative)
router queue     10 packets
nobody tells the senders these numbers: TCP has to probe

The trace is illustrative and counted in whole segments per round trip: a 20-packet link, a 10-packet queue, and both senders losing in the same round. Real losses are spread out and fast recovery briefly inflates cwnd. CUBIC (RFC 9438), the default in Linux, cuts to 0.7 of the window and regrows along a cubic curve, quickly at first and gently near the old peak. Newer algorithms such as BBR model the path's bandwidth and delay instead of waiting for loss.