What Is TCP Window Size?
TCP window size is the number of bytes a receiver will accept before the sender has to stop and wait for an acknowledgment.
That number caps the throughput any single connection can reach. A sender keeps at most that many unacknowledged bytes on the wire, then waits.
The value travels in the window field of every TCP header. It changes constantly, rising as the receiving application drains its buffer and falling as data piles up in it.
The mechanism exists for flow control, stopping a fast machine from drowning a slow one. On long paths that same mechanism holds you well below what the link could carry.
Receive Window vs Congestion Window
Two separate windows limit every TCP sender, and only one of them ever appears on the wire.
Receive window | Congestion window | |
Owned by | The receiver | The sender |
Protects | The receiver's buffer from overflowing | The network path from overloading |
Visible in a capture | Yes, in every single header | No, it only exists in the sender's memory |
How it changes | The receiver advertises a new number | The sender grows it on success and cuts it on loss |
Decided by | Buffer size and how fast the application reads | The sender's congestion control algorithm |
The smaller of the two wins, and the sender obeys that one. So a transfer can crawl while the advertised receive window looks generous. Network congestion had already shrunk the other window out of sight.
That invisibility trips up plenty of captures. When the receiver advertises plenty of room and the sender still trickles, stop reading the window field. Start counting retransmissions instead.
Why the Window Needs Scaling
The window field holds 16 bits, so it can express no more than 65,535 bytes.
That ceiling felt generous in 1981 and looks absurd now. A single gigabit link across a continent needs megabytes in flight, and 64 KB cannot come close.
Window scaling fixes it. RFC 7323 defines a factor that multiplies the advertised value by a power of two. A shift of up to 14 lifts the effective maximum to roughly one gigabyte.
One detail about scaling catches out everyone who captures traffic. The scale factor gets exchanged only in the SYN and the SYN-ACK.
An analyzer that missed the handshake cannot interpret any later window value, and Wireshark says so by reporting the scaling factor as unknown.
Window size also has nothing to do with segment size. It counts bytes allowed in flight, while the maximum transmission unit governs how large each packet can be.
How Window Size Caps Your Throughput
Throughput can never exceed the window divided by the round-trip time, whatever the link's rating says.
maximum throughput = window size / round-trip time
Run that arithmetic against a few real paths and the problem becomes obvious.
Link rate | Round trip | Bytes needed in flight | Throughput with a 64 KB window |
100 Mbps | 10 ms | 125 KB | 52 Mbps |
1 Gbps | 10 ms | 1.25 MB | 52 Mbps |
1 Gbps | 80 ms | 10 MB | 6.6 Mbps |
10 Gbps | 150 ms | 187.5 MB | 3.5 Mbps |
Look at rows two and three. The same gigabit link delivers 52 Mbps across a metro path and 6.6 Mbps across an ocean. The window simply cannot cover the extra distance.
Nothing failed in that last row either. The bytes-in-flight column holds the bandwidth-delay product, and any window below that number leaves capacity unused. That relationship is why latency, bandwidth and throughput have to be read together.
What Does a TCP Zero Window Mean?
A zero window means the receiver's buffer has filled completely, so the sender must stop sending data at once.
The receiver keeps acknowledging what already arrived while advertising a window of zero. The sender then pauses and sends occasional probes. The receiver replies with a window update as soon as space frees up.
That sequence points somewhere specific. A zero window blames the receiving application rather than the network, because something on that host stopped reading its socket fast enough.
Four causes account for most of them.
A worker thread blocked on a slow database call or a disk write.
A thread pool with nothing left to hand the incoming data to.
A garbage collection pause long enough to stall the reader.
A process pinned at 100 percent CPU and unable to drain its queue.
Wireshark names three related conditions, and the difference between them matters. ZeroWindow comes from the receiver, and Window Full comes from the sender that just filled the advertised space. ZeroWindowProbe is the sender checking whether anything changed.
A handful of zero windows on a busy server means very little. The same host producing them in a repeating pattern deserves investigation. We have traced those back to an undersized connection pool more than once.
How Do You Check and Change the Window?
Linux keeps the live values and the limits in two different places.
Command | What it shows or sets |
ss -i | Live send and receive window per socket, alongside the measured round-trip time |
sysctl net.ipv4.tcp_rmem | The minimum, default and maximum receive buffer, in that order |
sysctl net.ipv4.tcp_wmem | The same three values for the send buffer |
sysctl net.core.rmem_max | The ceiling any socket is allowed to request explicitly |
sysctl net.ipv4.tcp_moderate_rcvbuf | Whether receive-buffer autotuning is running, which it is by default |
Windows exposes the same controls through two tools.
Command | What it shows or sets |
netsh int tcp show global | The current receive window auto-tuning level |
netsh int tcp set global autotuninglevel=normal | Puts auto-tuning back to its default behavior |
Get-NetTCPSetting | Per-template settings, including auto-tuning, from PowerShell |
Read the third value of tcp_rmem as the number that matters. Autotuning grows the receive buffer toward that ceiling on its own. Raising the default achieves little while the ceiling stays low.
When Should You Leave the Window Alone?
You should leave it alone almost always, because autotuning has handled this correctly on both platforms for well over a decade.
Manual tuning earns its keep in one situation. You control both ends and the path runs long and fast. Bulk transfers such as replication or backup between distant data centers fit that shape.
Everywhere else something else is the bottleneck. Loss causes most of them, since every packet loss event halves the congestion window. Each recovery on a long path then costs another full round trip.
Two other causes turn up often enough to check first. A middlebox that strips the window scale option silently caps you at 64 KB. A slow-reading application keeps the advertised window small however large you size the buffer.
What to Watch Instead
Zero-window events and retransmission rates tell you more than any window figure on its own. Both cost little to collect, and both name the side that needs attention.
Track them beside round-trip time. The three together separate a distance problem from a loss problem from a slow application. The wider set of network performance metrics worth collecting comes with its own healthy ranges per workload.
Explore More IT Terms
Browse our comprehensive IT glossary to learn more about technology terminology.