The Dual-Window Mechanism
TCP throughput is governed by two independent window sizes: the Receive Window (rwnd) and the Congestion Window (cwnd). The effective transmission window is always min(rwnd, cwnd).
- Flow Control (rwnd): Prevents the sender from overwhelming the receiver. The receiver advertises its available buffer space in every ACK.
- Congestion Control (cwnd): Prevents the sender from overwhelming the network. This is estimated by the sender based on packet loss and RTT.
Congestion Control Algorithms
Standard TCP Reno/NewReno follows a specific lifecycle:
- Slow Start:
cwndstarts at Initial Congestion Window (IW - usually 10 segments in modern Linux) and grows exponentially (doubles every RTT) until it hits the Slow Start Threshold (ssthresh). - Congestion Avoidance: Once
cwnd >= ssthresh, growth becomes linear (1 segment per RTT) to probe bandwidth cautiously. - Fast Retransmit & Recovery: Triggered by 3 duplicate ACKs (packet loss without timeout).
ssthreshis set tocwnd / 2, andcwndis set tossthresh + 3. This avoids the penalty of a full RTO (Retransmission Timeout).
TCP CUBIC
Linux's default congestion control, CUBIC, replaces the linear window growth of Reno with a cubic function dependent on the time since the last congestion event. This allows for:
- Faster recovery on high-speed, high-latency (long fat) pipes.
- Protocol fairness and stability.
Inspection Commands
You can inspect TCP connection states and window sizes on Linux using ss: