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.
| Signal | What it indicates | Typical reaction |
|---|---|---|
| Three duplicate ACKs | One segment lost, later ones arrived | Fast retransmit, window reduced |
| Retransmission timeout | Severe loss or path failure | Window reset to one segment, slow start |
| ECN congestion mark | Router queue building up, no loss | Window reduced as for a loss |
| Rising round-trip time | Queue growing at the bottleneck | Delay-based algorithms slow down |
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.
| Algorithm | Primary signal | Window growth | Typical strength |
|---|---|---|---|
| Reno and NewReno | Packet loss | Linear, halved on loss | Simple, well understood baseline |
| CUBIC | Packet loss | Cubic function of time since last loss | Good use of high-bandwidth, long paths |
| BBR | Measured bandwidth and minimum RTT | Model-based pacing rate | High throughput despite random loss |
| Vegas | Round-trip time | Adjusts to keep queue small | Low delay, loses against loss-based flows |
| DCTCP | Fraction of ECN marks | Reduces in proportion to marking | Very low queues in data centers |
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.
| Parameter | Typical range | Effect |
|---|---|---|
| Initial congestion window | 10 segments, about 14 KB | Speed of short transfers |
| Round-trip time | Under 1 ms in a data center to over 600 ms via geostationary satellite | Rate of window growth and recovery |
| Loss rate | Near zero on fiber, percent range on poor radio | Frequency of window reductions |
| Socket buffer size | Tens of KB to tens of MB | Upper bound on data in flight |
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.