TCP Dynamic Windowing
Like many other protocols that perform error recovery, TCP uses a sliding window mechanism to perform flow control. The mechanics are probably familiar to most readers—the receiver states a window size, in bytes, using the Window field of its TCP segments sent over the TCP connection. This window is sometimes called the receiver's window, the receiver's advertised window, or the granted window. The sender can then send only one window's worth of data to the receiver without receiving an acknowledgement. The end goal with this basic dynamic windowing is to allow the receiver to dictate how fast the sender can send data, thereby protecting the receiver from running out of memory. The receiver can increase or decrease the sender's window size for the connection by changing the window size stated in subsequent TCP segments. For instance, in Figure 6-3, the web server would have needed a window size of at least 3000 to send the first three segments shown in the figure.
Interestingly, TCP senders limit their dynamic window based on two different factors—the popularly known advertised window, described in the previous paragraph, and another mechanism that allows the sender to react to packet loss by lowering the size of the window. This additional mechanism, defined in RFC 2581 as "TCP Congestion Control," defines the details of how TCP should react to segment loss by slowing down. In effect, a TCP sender uses a sliding window, with the sliding window being the smaller of the two possible values—either the window granted to the sender by the receiver, or the calculated window defined in RFC 2581. This calculated window is called the congestion window (CWND), and is the most important part of TCP Congestion Avoidance logic. This logic is summarized in the following list, with details to follow:
KEY 1. At connection establishment, CWND is set to a low value, often equal to one maximum POINT segment size (MSS).
2. If no segments are lost, CWND grows using Slow Start logic, which increases CWND at an exponential rate.
3. For each lost segment, CWND is halved.
4. After the lost segments have been successfully re-sent, CWND grows again, beginning with Slow Start.
5. After loss of segment(s), while CWND grows, it grows using Slow Start logic until CWND reaches a value of half the original CWND. Then, CWND slows down its growth, using an algorithm called Congestion Avoidance, which increases CWND at a linear rate.
More generally, the algorithm starts with a small window. The window grows rapidly, but when congestion occurs, the window is limited by lowering the CWND variable. Once the data is successfully re-sent, CWND can grow rapidly—but not too rapidly, because this TCP sender might have been causing the congestion that resulted in the original packet loss. The next few paragraphs take a closer look at the component steps in the list.
In Step 1, the TCP sender can send only one maximum size segment before requiring an acknowledgement—a relatively severe, small window. The TCP maximum segment size (MSS) defines the largest allowed size of the TCP Data field, not counting the TCP header itself. With the typical IP MTU default on most interfaces being 1500 bytes (MTU includes the IP header, by the way), the typical MSS is 1460.
In Step 2, CWND grows exponentially, using an algorithm called TCP Slow Start—a seemingly contradictory name. (Slow Start can be thought of as "slower than if there were no congestion window concept.") CWND is likely to grow to some number larger than the granted window over the course of a few seconds.
Most loss occurs because of congestion, so in Step 3, CWND is lowered quickly. The idea is simple: slow down TCP senders when packets are lost, which in turn should decrease network congestion. The reaction, halving CWND for each lost segment, means that the reaction is swift.
In Steps 4 and 5, the segments have been recovered, and the sender could be limiting its window based on the recently-lowered CWND. CWND can grow again at this point, but rather than rush immediately to the previous-high CWND value, the RFC calls for a less-aggressive growth rate as CWND approaches its value prior to the segment loss. Figure 6-4 depicts a graph of what happens with CWND upon segment loss, and how the sender grows CWND after the packet loss.
Figure 6-4 CWND Growth with Slow Start and Congestion Avoidance After Multiple Segment Loss
CWND
Figure 6-4 CWND Growth with Slow Start and Congestion Avoidance After Multiple Segment Loss
CWND

- Congestion Avoidance
The graph shows the changes to CWND from connection establishment through multiple segment loss. Because multiple segments were lost, the TCP sender halved CWND multiple times, and in this case, CWND was lowered to its minimum value—a single MSS. Before lowering CWND, the sender calculated a variable called Slow Start Threshold (SSThresh), which is half of the original CWND before segments were lost.
Now back to Steps 4 and 5. In Step 4, the sender grows CWND using the exponential Slow Start logic, until CWND reaches SSThresh, at which point it grows CWND more slowly, using TCP Congestion Avoidance logic. Essentially, the SSThresh variable identifies the threshold at which the sender stops using Slow Start logic, and transitions to using Congestion Avoidance logic, to grow CWND.
Continue reading here: TCP Header Miscellany
Was this article helpful?