After reading this question I'm still confused about the relationship between the receiver window and the congestion window in the context of TCP based communications.

The answer states that the congestion window is expanded(doubled for each ACK received for a successfully transmitted segment) and then halved upon reaching a congestion(ACKS are no longer returned at the rate at which data is being sent) in order to ensure "optimal" throughput.

However, it does not state how the receiver window is computed and its relationship with regards to the congestion window. What is the set of relationships between the two?

  • tcp is a two way street. While one party initiates the session, once that is done, there isn't really a notion of a sender and recipient - both parties are senders and receivers, so both parties ack each others data, and so both parties windows can be scaled. – Paul Sep 7 '15 at 13:21
  • @Paul So both windows(receiver window and congestion) scale? How? What is the relationship between them(when, why and how do they scale?) – Sebi Sep 7 '15 at 15:07

The receive window is the amount of data the receiver can take at once without getting overwhelmed. It is flow control imposed by the receiver.

The congestion window (note: it's the "congestion window"; there is no "transmission window", so your title is a little off) is the amount of data the network (the routers between the sender and receiver) can take at once without getting overwhelmed (that is, without causing or exacerbating congestion). The congestion window is can be thought of as a form of sender-imposed flow control.

Before we get into the congestion window, let's start with the details of the receive window.

The receive window is how much data the receiving TCP stack is willing to receive and buffer for the receiving app, before the receiving app reads the waiting data from the receiving TCP stack and frees those kernel buffers. The size of the receive window can be limited by implementation-specific details. For example, a Unix-like kernel may limit the receive window size by how many kernel message buffers (mbufs) the kernel is willing to allocate to each TCP connection.

Assuming you are not limited by resources on the receiver, you can calculate an optimal receive window to use for a given TCP connection. Basically, the receive window should be at least the "bandwidth * delay product" (BDP) of the TCP connection. So to use a typical 1300Mbps 802.11ac example, if you have a 1,300,000,000 bits per second link (this is your bandwidth), with a 0.003 second Round Trip Time (RTT; think "ping time"; this is your delay), your receive window should be at least 1,300,000,000 bits/sec * 0.003 sec = 3,900,000 bits, which is about 476KiBytes. Sizing the receive window to the BDP allows the sender to "fill the pipe", sending as much data into the network as the network can keep in-flight until there's been enough time to get an Ack back to the sender. Anything less than this, and the sender won't be able to transmit continuously; instead (once TCP slow start ramps up enough) it will send a receive-window-sized burst, but it will be done injecting that burst into the network before it gets an Ack back telling it that there's more room in the receive window. So it will have to pause and wait for that Ack before it knows it can send more without overwhelming the receiver's TCP stack. That time it spends paused, waiting for an Ack is lost time it could have spent transmitting.

So that's what the receive window is, and how it's calculated. Now let's look at the congestion window.

The congestion window is one of the things the sender keeps track of to make sure it's not causing network congestion for the network hops (routers, inter-router links) between the sender and receiver. Eventually innovations like Explicit Congestion Notification (ECN) will be widely deployed, allowing routers to notify TCP senders of congestion. But until then, TCP senders need try to detect and avoid congestion in other ways, and most of that comes from starting out transmitting packets slowly to probe the network for how fast it can go without losing packets, interpreting packet loss as a sign of congestion, greatly reducing packet transmission rate when loss occurs, and slowly ramping back up again.

The current standards-track RFC on TCP Congestion Control, RFC 5681, says that the Congestion Window should be initially calculated as being between 2-4 times the TCP Maximum Segment Size (MSS; like the TCP-layer equivalent of an MTU); specifically, 2-4 times the TCP MSS that the sender is tracking. This is the Sender MSS or SMSS. The RFC also states that the sender should respect whichever is lower between the congestion window and the receive window. That is, even if the network is fast and uncongested (and thus the congestion window has grown larger than the receive window), there's no sense in sending more data into the network than the receiver can handle; that'll just end up overwhelming the receiver and causing it to drop the packets after they got all the way across the network successfully.

So that's the relationship between the congestion window and the receive window. One is receiver-side flow control so the receiver doesn't get overwhelmed, and the other is sender-side flow control so the routers in the network don't get overwhelmed. When deciding whether or not it can put more packets in-flight, the TCP sender has to look at both the congestion window and the receive window and honor whichever is lower.

The congestion window typically starts at about 3 SMSSes (3 * 1448 bytes = 4344 bytes), and during TCP Slow Start, increases by up to 1 SMSS (1448 bytes) per Ack assuming at least 1 SMSS' worth of previously unAcked bytes got Acked. After Slow Start, the Congestion Avoidance algorithm kicks in, and the Congestion Window increases by no more than 1 SMSS per RTT. If the sender detects packet loss, it interprets that as congestion, and cuts the congestion window basically in half for easily-recoverable loss (Fast Retransmit / Fast Recovery, as triggered by "Triple Duplicate Acks"), and slashes it down to 1 SMSS for more serious loss scenarios (no Acks received before the retransmission timer expires).

Please note that your Question contains an error. It is wrong to say that the congestion window is doubled when the sender receives an Ack. The congestion window starts at typically 3 SMSSes and is increased by no more than one SMSS per Ack'd SMSS. When loss occurs, the congestion window is cut basically in half or worse. In fact, the congestion window resizing policy is often summed up as "additive-increase, multiplicative-decrease".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.