← Module 04 · Layer 4: Transport

Flow Control & Congestion Control

Two different problems, both solved by TCP (Transmission Control Protocol) dynamically shrinking or growing how much data is allowed to be in flight at once.

Short answer: Flow control protects the receiver using its advertised window (rwnd). Congestion control protects the network path using the sender's congestion window (cwnd) and algorithm. The smaller window normally limits outstanding data.

Before this: TCP header fields and the TCP handshake.

Two different problems, two different mechanisms

Both mechanisms affect "how much can I send right now," but they protect different resources.

Picture carts carrying parts to a workbench through a shared factory corridor. Flow control is the worker reporting how many more parts fit on the bench. Congestion control is the dispatcher limiting carts in transit when deliveries slow down or fail. The bench may be empty while the corridor is jammed, or full while the corridor is clear. With Explicit Congestion Notification (ECN), network devices can also mark congestion, like a warning light in the corridor; loss is not the only possible signal.

Flow control: The receive window

The Window Size field in the TCP header advertises a receive budget beginning at the acknowledgment number, with negotiated window scaling applied after the SYN exchange. It reflects how much data the receiving TCP is prepared to accept. If its application reads slowly, the receiver can advertise a smaller window, which the sender must respect. A window of 0 pauses normal new data in that direction, not ACKs or the entire connection. The sender periodically probes so it can discover when the receive window reopens.

RECEIVE WINDOW SENDER RECEIVER sender keeps transmitting while the window allows window = 0: sender must pause and probe periodically window update: receiver reopens the window, sending resumes
The receiver, not the network, sets this limit. It's purely about protecting the receiving application's buffer from being overrun.

Congestion control: What the sender infers on its own

The receive window says nothing about capacity along the path. The sender therefore maintains a congestion window (cwnd), which is not a TCP header field. The classic Reno-style model below responds to ACKs, inferred loss, and optionally ECN. Other algorithms, including CUBIC, use different growth and reduction rules. In the factory, cwnd is the dispatcher's cap on outstanding carts, not the workbench's free space.

CONGESTION WINDOW (cwnd) TIME ssthresh slow start (exponential) congestion avoidance (linear) loss detected: cwnd cut in half
A schematic Reno-style congestion-window curve, not a measured throughput trace. The dashed line marks the initial ssthresh; recovery updates the threshold. Other congestion-control algorithms and application limits can produce different shapes.

Worked example: the window is a byte budget

Suppose rwnd = 65,536 bytes, cwnd = 32,768 bytes, and 12,288 bytes remain unacknowledged. Ignoring recovery and other limits, the sender can put another min(65,536, 32,768) - 12,288 = 20,480 bytes in flight. The dispatcher has room for more carts, but only within the smaller of the corridor budget and the bench budget.

At a steady 50 ms round-trip time, a 32,768-byte flight limit corresponds to roughly 32,768 / 0.05 = 655,360 bytes/s, about 5.24 Mbit/s before overhead. This is a window-limited estimate, not a throughput promise. Loss, ACK behavior, pacing, sender data availability, and receiver processing can reduce it. A faster Ethernet link alone does not enlarge this budget.

Tell the limits apart

EvidenceCheckInterpretation
Receiver advertises a zero windowInspect receiver buffer pressure and whether the application reads promptlyFlow control is stopping new normal data; zero-window probes can still occur.
Retransmissions with an open receive windowCompare captures at both ends, ACK timing, and congestion signalsLoss or reordering may limit progress. A one-sided capture can also miss packets.
Small raw Window field in a captureInspect Window Scale options in both SYNsPost-handshake windows may be scaled; the raw 16-bit field alone is not the effective byte limit.
Need the actual cwndUse sender-side TCP telemetry; Linux iproute2 offers ss -ticwnd is local sender state and cannot be read directly from a packet header. Tool units must be checked before comparing values.
THE ACTUAL LIMIT IS WHICHEVER WINDOW IS SMALLER

A sender never gets to use more than min(receive window, congestion window) worth of unacknowledged data at once. A fast local network with a slow, congested path to the destination will be limited by cwnd; a fast path to a receiver with a tiny buffer will be limited by the receive window. Either one alone tells an incomplete story.

Continue with MTU and fragmentation or HTTP transport behavior.