TCP congestion control

On this page 7

TCP congestion control is the set of algorithms a TCP sender uses to limit how much unacknowledged data it puts into the network, so that the shared path between sender and receiver is used efficiently without being overloaded. Among transport protocols, it is the mechanism that keeps the internet stable: each sender probes for available capacity and backs off when it detects congestion, usually through packet loss or rising delay.

Congestion control is distinct from flow control. Flow control protects the receiver through the advertised receive window, while congestion control protects the network through a sender-side congestion window (cwnd). At any moment, a TCP sender may have no more data in flight than the smaller of the two windows.

How TCP congestion control regulates the sending rate

TCP congestion control works by adjusting the congestion window, measured in bytes or in segments of MSS size. Because a sender can transmit roughly one window per round-trip time, the achievable throughput is approximately cwnd divided by RTT. Growing the window raises the rate; shrinking it lowers the rate.

Classic algorithms, standardized for TCP Reno and NewReno, use four phases. Slow start begins with a small initial window, today usually 10 segments, and roughly doubles it every round trip. When the window reaches the slow start threshold (ssthresh), the sender switches to congestion avoidance and adds about one segment per round trip. A loss signal then triggers fast retransmit and fast recovery, which halve the window instead of restarting from the beginning.

This pattern is called additive increase, multiplicative decrease (AIMD). It is the reason why several TCP flows sharing a bottleneck tend to converge toward a roughly fair share of its capacity over time, although flows with shorter round-trip times usually obtain more.

Congestion signals and how the sender reacts

A sender cannot see the network directly, so it infers congestion from indirect signals. Different algorithms trust different signals, which explains much of their behavior. The table shows the main signals and the typical reaction of a loss-based algorithm.

SignalWhat it indicatesTypical reaction
Three duplicate ACKsOne segment lost, later ones arrivedFast retransmit, window reduced
Retransmission timeoutSevere loss or path failureWindow reset to one segment, slow start
ECN congestion markRouter queue building up, no lossWindow reduced as for a loss
Rising round-trip timeQueue growing at the bottleneckDelay-based algorithms slow down
Congestion signals and typical reactions

Explicit Congestion Notification (ECN) lets routers mark packets instead of dropping them, which avoids retransmissions. It requires support at both endpoints and an active queue management scheme in the network, so its benefit depends on the path.

Main TCP congestion control algorithms

Many algorithms implement the same basic goal with different growth functions and signals. Operating systems choose one default algorithm and usually allow it to be changed per host or per socket. The table compares the most widely discussed ones.

AlgorithmPrimary signalWindow growthTypical strength
Reno and NewRenoPacket lossLinear, halved on lossSimple, well understood baseline
CUBICPacket lossCubic function of time since last lossGood use of high-bandwidth, long paths
BBRMeasured bandwidth and minimum RTTModel-based pacing rateHigh throughput despite random loss
VegasRound-trip timeAdjusts to keep queue smallLow delay, loses against loss-based flows
DCTCPFraction of ECN marksReduces in proportion to markingVery low queues in data centers
Widely used congestion control algorithms

CUBIC is the default in Linux and in current Windows and macOS versions. BBR, developed for large content delivery networks, estimates the bottleneck bandwidth and minimum RTT and paces packets accordingly. It can perform far better on lossy long-distance links, but early versions were criticized for unfairness toward CUBIC flows in shallow buffers, which later revisions try to address.

Factors that limit throughput under congestion control

Even with a modern algorithm, the bandwidth-delay product sets the window a sender needs. A 1 Gbps path with a 100 millisecond RTT requires about 12.5 MB in flight, so the TCP window size, socket buffers and window scaling must allow that much. Otherwise the connection is limited by buffers rather than by the network.

ParameterTypical rangeEffect
Initial congestion window10 segments, about 14 KBSpeed of short transfers
Round-trip timeUnder 1 ms in a data center to over 600 ms via geostationary satelliteRate of window growth and recovery
Loss rateNear zero on fiber, percent range on poor radioFrequency of window reductions
Socket buffer sizeTens of KB to tens of MBUpper bound on data in flight
Parameters that shape TCP throughput

For loss-based algorithms, throughput falls roughly with the square root of the loss rate. This is why a link with only a fraction of a percent of random radio loss can make a long-distance TCP transfer dramatically slower than the link capacity suggests.

Common problems and misconceptions

Several recurring issues are wrongly blamed on bandwidth when they are really congestion control effects:

  • Bufferbloat: oversized router buffers let loss-based TCP fill long queues, adding hundreds of milliseconds of latency for every flow on the link.
  • Wireless loss misread as congestion: radio errors reduce the window even though the path is not overloaded.
  • Single-stream tests on long paths show low speeds caused by RTT and buffers rather than by the link.
  • UDP traffic without congestion control can starve TCP flows that politely back off.

Active queue management such as CoDel or FQ-CoDel at the bottleneck addresses bufferbloat directly. Changing the end-host algorithm helps only when the sender is the right place to fix the problem, so measuring RTT, loss and queue delay first prevents guesswork.

The short version

TCP congestion control is how a computer decides how fast to send data without jamming the network for everyone else. It starts carefully, speeds up while things go well, and slows down as soon as it sees signs of a traffic jam.

It resembles merging onto a busy highway. A good driver accelerates when there is space and eases off when brake lights appear ahead. Millions of connections behaving this way keep the internet usable instead of grinding to a halt.

Where it makes a difference

A media company copies nightly video archives of several hundred gigabytes from a European office to a storage site in Asia over a 1 Gbps link with a 220 millisecond round-trip time and occasional loss of about 0.1 percent. With the default CUBIC algorithm and standard buffers, a single transfer stream averages only around 150 Mbps.

The engineers first raise the socket buffers to 32 MB so the window can cover the bandwidth-delay product, which lifts throughput noticeably. They then enable BBR on the sending servers, which no longer treats each random loss as congestion. The transfers settle at roughly 800 Mbps, and the nightly job finishes hours earlier without any change to the link itself.