TCP window size

On this page 7

TCP window size is the amount of data, in bytes, that a TCP sender is allowed to have in flight without acknowledgment before it must stop and wait. Among transport protocols, it is the core mechanism of flow control in TCP: the receiver advertises a receive window (rwnd) that reflects its free buffer space, and the sender never exceeds it.

The usable window also depends on the sender’s congestion window (cwnd), so the effective limit is the smaller of rwnd and cwnd. Because throughput on a single connection can never exceed the window divided by the round-trip time, window size directly decides how fast TCP can move data across long or fast networks.

How the sliding window works

TCP numbers every byte it sends. Each acknowledgment from the receiver confirms bytes up to a sequence number and carries a 16-bit window field that states how many further bytes the receiver can accept. The sender may transmit any byte that falls inside this sliding window, which moves forward as acknowledgments arrive.

When an application on the receiving side reads data slowly, its socket buffer fills, the advertised window shrinks and the sender slows down. If the buffer fills completely, the receiver advertises a zero window and the sender stops, periodically sending window probes until space reopens. This keeps a fast sender from overwhelming a slow receiver.

The window is distinct from segment size. The MSS limits how much data fits into one segment, typically 1,460 bytes on standard Ethernet with a 1,500-byte MTU, while the window limits how many such segments may be outstanding at once.

Window scaling and the bandwidth-delay product

The original header field allows a maximum window of 65,535 bytes, which became a bottleneck once networks grew faster. The window scale option defined in RFC 7323 multiplies the advertised value by a power of two, negotiated during the TCP handshake, with a shift count of up to 14. This raises the maximum window to about 1 GiB.

The window needed for full speed equals the bandwidth-delay product (BDP): link bandwidth multiplied by round-trip time. The table below shows how quickly the required window grows on fast or distant paths.

BandwidthRound-trip timeRequired windowWithout scaling
100 Mbit/s10 msAbout 125 KBLimited to about 52 Mbit/s
1 Gbit/s20 msAbout 2.5 MBLimited to about 26 Mbit/s
1 Gbit/s100 msAbout 12.5 MBLimited to about 5 Mbit/s
10 Gbit/s50 msAbout 62.5 MBLimited to about 10 Mbit/s
Window needed to fill a path

The ceiling follows from a simple formula: maximum throughput = window / RTT. A 64 KB window over a 100 ms path yields at most about 5 Mbit/s regardless of link capacity, which explains why transfers between continents can be slow on connections that perform well locally.

Receive window versus congestion window

Two different windows constrain a sender, and confusing them is a common source of tuning errors. The comparison below separates their roles.

PropertyReceive window (rwnd)Congestion window (cwnd)
Controlled byReceiverSender
PurposeFlow control, protects the receiverCongestion control, protects the network
Visible on the wireYes, in every TCP headerNo, internal sender state
Driven byFree socket buffer spaceLoss, delay and the congestion algorithm
Typical growthAuto-tuned by the operating systemSlow start, then algorithm-specific
The two windows that limit TCP

TCP congestion control algorithms such as CUBIC or BBR shape cwnd, starting from an initial window of about 10 segments on modern systems. A large receive window does not help when packet loss keeps cwnd small, and a well-behaved congestion window cannot help when the receiver advertises a small rwnd.

Tuning window size in practice

Modern operating systems use receive window auto-tuning, growing socket buffers as a connection shows a high BDP. Manual tuning is now mostly limited to high-throughput, high-latency paths such as data replication between distant data centers or scientific transfers.

PlatformMechanismTypical setting
Linuxtcp_rmem and tcp_wmem sysctlsMaximum raised to tens of MB for long paths
WindowsReceive window auto-tuning levelNormal level, which permits scaling
ApplicationsSO_RCVBUF and SO_SNDBUF socket optionsFixed buffers, which can disable auto-tuning
Measurement toolsWindow option in iPerf and similar toolsSet to at least the path BDP
Where window size is usually configured

A frequent mistake is setting a fixed socket buffer in an application, which on Linux turns off auto-tuning for that socket and can lock the window to a value far below the BDP. Another is assuming that a larger buffer is always better: oversized buffers on congested links contribute to bufferbloat, raising latency for other traffic.

Diagnosing window problems

Window limits show up as throughput that plateaus well below link capacity while the path shows little packet loss. Packet captures make the cause visible, because analyzers track the advertised window over time and flag specific events.

  • Zero window events mean the receiving application is not reading data fast enough.
  • Window full events mean the sender has used the entire advertised window and is waiting.
  • Missing window scale option in the handshake, often caused by an old middlebox, caps the window at 64 KB.
  • Throughput equal to window divided by RTT across many tests points to a window limit rather than a capacity limit.

Because the scale factor is negotiated only once, captures that miss the handshake show unscaled raw values, so analysis should start from the SYN packets whenever possible.

The simple explanation

When one computer sends data to another over TCP, it cannot send everything at once. The receiver says how much it can take right now. That amount is the window. The sender sends up to that amount, then waits for a confirmation before sending more.

Picture a conveyor belt between two workers. The second worker says how many boxes fit on the table. If the table is small and the belt is long, the first worker spends most of the time waiting. A bigger window keeps the belt full, which matters most when the distance is long.

How it is used in practice

A company replicates nightly database backups from Europe to a disaster recovery site in North America over a dedicated 1 Gbit/s circuit with a round-trip time of about 90 ms. The transfer runs at only about 45 Mbit/s and does not finish before the morning.

A packet capture shows that the backup software sets a fixed 512 KB receive buffer, and window full events appear constantly. With a BDP of roughly 11 MB, the window allows only a small fraction of the circuit. The engineers remove the fixed buffer setting and raise the Linux tcp_rmem maximum to 32 MB. Throughput rises to about 900 Mbit/s, and the nightly job completes in well under an hour.