TCP Slow Start and Congestion Avoidance
TCP slow start and congestion avoidance are the rules TCP uses to control how much data a connection may have in flight. They increase the sender’s allowance when delivery succeeds and reduce it when the network appears overloaded.
The problem: capacity is not known in advance
A TCP sender knows the destination address, but it usually does not know how much traffic the path can carry. The path may include a fast local network, a slower link, busy routers, or a shared mobile connection. Sending at the maximum possible rate immediately could fill router queues and cause widespread packet loss.
Without congestion control, many senders could keep transmitting after the path became full. Packets would be dropped, delays would grow, and retransmissions would add even more traffic. TCP instead probes the path: start cautiously, increase the rate while delivery looks healthy, and back off when loss suggests that the current rate is too high.
A TCP sender tracks this allowance in the congestion window, or cwnd. It is the amount of unacknowledged data the sender is allowed to have in the network because of congestion concerns. It is commonly described in bytes or in segments. A segment is one TCP packet’s worth of data; its maximum payload is commonly called the maximum segment size, or MSS.
The sender also respects the receiver’s advertised window, which limits how much data the receiving application and its buffers can accept. In practice, the sender’s outstanding data is limited by the smaller of cwnd and that receiver limit. Slow start and congestion avoidance change cwnd; they do not replace the receiver’s flow-control limit.
Slow start: grow quickly from a small beginning
At the start of a connection, TCP initializes cwnd to a relatively small value. The exact initial value depends on the TCP implementation and protocol guidance. The sender transmits up to that amount, then waits for acknowledgements.
An acknowledgement, or ACK, is a TCP message indicating that the receiver has received bytes through a particular sequence number. Each ACK tells the sender that some data has successfully crossed the path and that space has opened for more data.
During slow start, each new ACK increases cwnd by approximately one MSS, subject to implementation details. If a window contains N segments and all are acknowledged, the window therefore grows by about N segments over one round trip. The result is roughly exponential growth per round trip:
round trip cwnd (approximate segments)
start 1
1 2
2 4
3 8
4 16
This is called slow start because it begins with a small sending window, not because its growth remains slow. Once the sender has evidence that the path can carry more traffic, the window can become large quickly.
TCP normally leaves slow start when cwnd reaches a second value called slow-start threshold, or ssthresh. The threshold marks the point where exponential probing should give way to more cautious growth. It may be configured initially, but it is also adjusted after congestion is detected.
Congestion avoidance: probe more carefully
After cwnd reaches ssthresh, TCP enters congestion avoidance. The traditional behavior is additive increase: increase the window by about one MSS per round trip, rather than doubling it each round trip.
One common way to approximate that behavior is to add a fraction of an MSS for each ACK, with the fraction based on the current window. If cwnd is measured in bytes and the MSS is M, the increase for an ACK can be approximated as:
cwnd += M * M / cwnd
After roughly one full window of ACKs, those small increments add up to about one MSS. This lets TCP continue searching for unused capacity without making a sudden, large jump.
The important feedback loop is:
- Send no more than the current
cwndallows. - Use ACKs as evidence that data arrived.
- Increase
cwndwhen ACKs continue arriving. - Treat loss as evidence that the current sending rate may be too high.
The sender’s actual rate also depends on the round-trip time, or RTT: the time for data to reach the receiver and for its ACK to return. A larger window can keep more data in flight, while a longer RTT means those bytes take longer to receive acknowledgement. Roughly, a connection’s possible throughput is its in-flight window divided by its RTT, subject to other limits.
Loss causes a reduction
TCP can infer loss when a retransmission timer expires or when it receives several duplicate ACKs. A duplicate ACK repeats the same acknowledgement because a later segment arrived while an earlier one was missing. These signals are not perfect proof of congestion—wireless errors and packet reordering can also cause them—but traditional TCP treats them as useful congestion clues.
The response depends on the signal and on the congestion-control algorithm. In the classic Reno-style behavior, a timeout is treated as severe congestion: TCP reduces ssthresh, retransmits the missing data, and returns cwnd to a small initial value, entering slow start again. A run of duplicate ACKs can trigger fast retransmit, which resends the presumed missing segment without waiting for the timer, followed by fast recovery, which reduces cwnd but avoids starting from the smallest window.
A common reduction sets ssthresh to roughly half of the previous in-flight window. After recovery, congestion avoidance resumes and TCP increases the window again. This familiar pattern—additive increase, then multiplicative decrease—is often called AIMD. It lets a connection reclaim capacity gradually while quickly backing away from a congested level.
Modern TCP implementations may use algorithms such as CUBIC or BBR instead of Reno’s exact formulas. Their growth and loss responses differ, but the central purpose remains: regulate in-flight data using delivery feedback, avoid persistently overloading the path, and discover the capacity available to this connection.
Where you may have seen it
A packet-capture tool may show cwnd, retransmissions, duplicate ACKs, or a slow transfer that accelerates after connection setup. Operating-system networking metrics and performance reports may expose the congestion window or a congestion-control setting. These are views of the same probing process: TCP is learning how much data the network can carry, one acknowledgement and one loss signal at a time.