fast recovery
Picture a busy assembly line that has one part go missing. Two reactions are possible. You could shut the whole line down, clear everything, and restart slowly from scratch — overkill if only one part was lost. Or you could keep the line moving, slot in the missing part, and just trim the speed a little. Fast recovery is TCP choosing the second, sensible reaction after a fast retransmit: do not slam the brakes to a dead stop, because the steady flow of duplicate ACKs proves the path is still delivering packets.
When fast retransmit fires on three duplicate ACKs, classic TCP (Reno) enters fast recovery. Instead of crashing the congestion window down to one packet (which is what a timeout does), it HALVES the window — the multiplicative-decrease step of AIMD — and sets ssthresh to that halved value. Crucially, it then keeps sending: each further duplicate ACK is evidence that one more packet has left the network and reached the receiver, so the sender is allowed to send one new packet to keep the pipe full. When the acknowledgment for the retransmitted segment finally arrives, the sender deflates the window to the new ssthresh and resumes congestion avoidance — never having returned to slow start.
The reasoning is subtle but important: a single packet lost amid a stream of arriving packets signals mild congestion, so a gentle multiplicative decrease is the right response. A retransmission timeout, by contrast, means the sender heard nothing back at all — possibly a severe stall — so it justifies the harsher reset to slow start. Fast recovery is the difference between TCP gliding smoothly through ordinary, occasional losses and lurching to a near halt at every hiccup. It is what gives modern TCP its characteristic shallow sawtooth rather than deep sawtooth crashes.
With cwnd at 80 packets, three duplicate ACKs arrive. Fast retransmit resends the lost segment; fast recovery sets ssthresh = 40 and cwnd = 40 (a halving), and the sender keeps trickling out new packets as more dup ACKs arrive. Contrast a timeout on the same flow: that would have set cwnd = 1 and restarted slow start from the bottom — a far deeper, slower dip.
On triple dup ACKs TCP merely halves and keeps flowing; only a timeout forces the harsh crash back to slow start.
Fast recovery is what makes a duplicate-ACK loss cost far less throughput than a timeout. This is also why a single timeout is so costly: TCP interprets silence as severe trouble and dives all the way back to slow start, whereas a loss detected via dup ACKs is treated as a routine bump.