Slow start and exponential growth
TCP does not immediately transmit at the network's full capacity. It starts with a small congestion window (cwnd): the number of bytes it can send without waiting for an acknowledgment. Typically cwnd begins at 1 or 2 segments. For each segment acknowledged, cwnd grows by 1, so cwnd doubles every round-trip: 1, 2, 4, 8, 16. This exponential growth is slow start: it rapidly probes the network's capacity without overwhelming it. Slow start continues until a loss is detected or a threshold is reached.
Congestion avoidance and backoff
Once a threshold (ssthresh) is reached, TCP enters congestion avoidance: cwnd grows by 1 per round-trip, linear rather than exponential. This is slower but steadier. If a packet is lost (indicated by a retransmit timeout or duplicate acknowledgments), TCP assumes congestion: it cuts cwnd to 1 or ssthresh/2, depending on the loss detection method, and restarts slow start or congestion avoidance. This repeated probing, backup, and growth lets TCP find the bottleneck bandwidth and stay near it without overflowing the network.
Modern refinements
Classic TCP can underutilize high-bandwidth networks (satellite links, intercontinental links) because backoff is aggressive and growth is slow. Modern algorithms (Cubic, BBR) measure latency or loss rate more intelligently. BBR (Bottleneck Bandwidth and Round-trip time) measures actual delivery rate and adjusts cwnd based on bandwidth and RTT, rather than waiting for loss. These algorithms are fairer and faster, though not yet universally adopted.