Networking · Concept · 9 min read

TCP Window Size, and Why It Caps Your Throughput

The TCP window size is how much data a sender may have unacknowledged at once. It is flow control, and when it is too small for a link, it caps throughput, not the bandwidth.

Written by Marko Ristic, Editor Updated Sep 17, 2026
65,535byte maximum window without scaling (16-bit field)
1 GBabout the scaled maximum with the window scale option
14the maximum window-scale shift count
W/RTTthe throughput cap: window over round-trip time
Short answer

The TCP window size is how much data a sender is allowed to have in flight, unacknowledged, at any moment. The receiver advertises it in every segment: a number that says how many more bytes it is currently willing to accept into its buffer.

The sender may send up to that much and then must wait for an acknowledgment. This is TCP flow control, stopping a fast sender from overwhelming a slow receiver.

The header field is only 16 bits, so the raw maximum is 65,535 bytes, but a window scale option negotiated at setup shifts that up to about a gigabyte, needed on fast, high-latency links. If the window is too small for the link, throughput is capped no matter the bandwidth.

  • The TCP window size is how much unacknowledged data may be in flight
  • The receiver advertises it to control the sender, which is flow control
  • The header field is 16 bits, so 65,535 bytes without scaling
  • The window scale option raises the ceiling to about a gigabyte
  • A window too small for the link caps throughput below the link speed
On this page

What it isWhat the TCP window size is

The window is the answer to a simple question: how much can the sender send before it has to stop and wait.

It is the amount of in-flight data allowed. The TCP window size is the number of bytes a sender may have sent but not yet had acknowledged. Up to the window, the sender keeps sending; at the window, it waits for acknowledgments to come back before sending more.

The receiver advertises it. The window is carried in the TCP header, a field that states the number of bytes the sender of that segment is currently willing to receive. Because it travels in every segment, each side continuously tells the other how much room it has. This is the receive window, and it lives in the TCP header.

It reflects the receiver's buffer. The window is essentially how much free space the receiver has in its buffer right now. As the application reads data out of the buffer, the space frees up and the advertised window grows; if the application is slow to read, the window shrinks.

Flow controlHow flow control works

Flow control is the whole reason the window exists, and it is a feedback loop.

It matches the sender to the receiver. Flow control keeps a fast sender from overwhelming a slow receiver. The receiver's advertised window is the throttle: the sender can never have more unacknowledged data outstanding than the receiver has said it can hold.

The window slides. As each ACK arrives, the left edge of the window moves forward and new data can be sent, so the window slides along the byte stream. This sliding window mechanism is what lets TCP keep data flowing continuously rather than sending one segment and waiting for each one.

A zero window pauses the sender. If the receiver's buffer fills completely, it advertises a window of zero, which tells the sender to stop. When space frees up, the receiver sends a window update, and the sender resumes. This is how TCP applies the brakes cleanly instead of dropping data.

The limit and scalingThe 16-bit limit and window scaling

The original field was too small for modern links, and the fix is an option.

The raw field maxes at 65,535 bytes. The window field in the TCP header is 16 bits, so the largest window it can express directly is 65,535 bytes. On a fast, high-latency link that is far too little to keep the pipe full.

Window scaling raises the ceiling. The TCP window scale option, defined in RFC 7323, increases the receive window above its former maximum of 65,535 bytes. The window value is left-shifted by a shift count, and a maximum shift of 14 may be used, which pushes the effective window up to roughly a gigabyte.

It is negotiated once, at setup. Window scaling is agreed during the three-way handshake and applies for the life of the connection. If either side does not support it, the connection falls back to the unscaled 65,535-byte ceiling, which is a common hidden cause of poor throughput on long links.

Window and throughputWindow size and throughput

This is where the window stops being abstract and starts explaining slow transfers.

Throughput is window divided by round-trip time (RTT). A sender can have at most one window of data in flight per round trip, unlike UDP, which has no such feedback, so the maximum throughput of a single TCP connection is the TCP window size divided by the RTT. Double the latency with the same window and you halve the throughput.

The window must cover the bandwidth delay product. To fill a link, the TCP window has to be at least the bandwidth delay product (BDP): the link bandwidth multiplied by the RTT. On a long fat network, a fast link with high latency, the unscaled 65,535-byte window is nowhere near enough, which is what window scaling exists to fix.

More bandwidth alone does not help. If the window is the bottleneck, upgrading the link does nothing for a single connection, because the sender still stops after one window per round trip. The fix is a larger window, through scaling, not more bandwidth.

A worked example

Take a 1 Gbps network path with an RTT of 50 ms. The bandwidth delay product is 1,000,000,000 bits per second times 0.05 seconds, which is 50,000,000 bits, or about 6.25 MB. That is the TCP window size needed to keep the path full.

An unscaled window of 65,535 bytes on the same path allows 65,535 bytes every 50 ms, about 1.3 MB per second, or roughly 10 Mbps. The link is 1 Gbps and one TCP connection gets one percent of it. The window field, not the network, is the limit.

Reaching 6.25 MB takes a scale factor of at least 7, because 65,535 shifted left by 7 bits is about 8 MB. Both hosts send their shift count in the SYN and SYN-ACK packets, and each side applies the other's factor to every window value it receives.

Receive vs congestionReceive window versus congestion window

Two windows govern how much a sender sends, and they are often confused.

The receive window is the receiver's limit. The receive window, the one advertised in the header, is flow control: it protects the receiver from being overrun. It says nothing about the state of the network in between.

The congestion window is the sender's limit. The congestion window is the sender's own estimate of how much the network can carry without dropping packets. It is not advertised; the sender computes it and adjusts it as it detects loss.

The sender uses the smaller of the two. At any moment a sender may have in flight no more than the minimum of the receive window and the congestion window. Flow control and congestion control both apply, and whichever is tighter wins.

TuningChecking and tuning the TCP window size on Windows and Linux

Current operating systems size the TCP receive window automatically, so tuning is mostly a matter of confirming that nothing has switched the feature off. The checks are short.

Windows

Microsoft's performance tuning documentation says older Windows network stacks used a fixed receive window of 65,535 bytes, and that current versions use TCP receive window autotuning, negotiated during the TCP handshake.

The default autotuning level is Normal, which that page lists with a scale factor of 8. The other levels are Disabled, Highly Restricted, Restricted and Experimental.

netsh interface tcp show global
Get-NetTCPSetting | Select SettingName, AutoTuningLevelLocal

If the level shows disabled, the TCP window is held at its default size and a long path will be slow. The same Microsoft page warns that a network device that does not support the window scale option can break scaled connections, and the fix there is the device, not the server.

Linux

The kernel documentation lists three settings that matter, read and changed with sysctl.

SettingWhat it controls
net.ipv4.tcp_window_scalingWindow scaling on or off, enabled by default
net.ipv4.tcp_moderate_rcvbufReceive buffer autotuning, enabled by default
net.ipv4.tcp_rmemThree values: min, default and max receive buffer in bytes

The max value of tcp_rmem is the ceiling autotuning can grow the buffer to, so it caps the TCP receive window a Linux server will ever advertise. On a long fat network, raise that max to at least the bandwidth delay product of the path. The matching send side setting is net.ipv4.tcp_wmem.

Applications can also fix the buffer themselves with the SO_RCVBUF socket option, and on Linux that turns autotuning off for that socket. A slow transfer from one application on an otherwise fast server is often this.

In a captureSeeing the window at work

The window is not abstract in a packet capture; it is a value on every segment, and watching it explains a lot.

Every segment carries the current window. In a capture from tcpdump or Wireshark, each TCP segment shows the window the sender is advertising at that instant. Reading that value across a connection shows the receiver opening and closing its window as its application drains the buffer or falls behind.

A shrinking window means the receiver is behind. If the advertised window steadily drops toward zero, the receiving application is not reading the data fast enough, so the network is delivering faster than the host consumes. The window closing is the symptom, and the slow application is the cause.

Zero-window and window-full events stand out. A capture flags a zero-window when the receiver stops the sender, and a window-full when the sender has sent a full window and is waiting. A burst of these on a path that should be fast points at flow control, not the network, as the limit.

The scale factor is set only in the handshake. Because window scaling is negotiated once in the SYN and SYN-ACK packets, a capture that misses the start of a connection cannot know the true window, since it never saw the shift value. That is a common trap when reading a mid-stream trace.

PitfallsWhere people go wrong

Blaming bandwidth for a slow single transfer. One TCP connection is capped at window over round-trip time. A slow transfer on a fast link is often a window too small for the latency, not a lack of bandwidth.

Forgetting window scaling can be missing. If either end does not negotiate scaling, the window is stuck at 65,535 bytes and throughput on a long link is throttled. A packet capture showing a tiny window on a fast path points straight at this.

Confusing the receive and congestion windows. The receiver advertises the receive window; the sender computes the congestion window. Tuning one when the other is the bottleneck changes nothing.

Treating a zero window as an error. A window of zero is normal flow control, the receiver saying wait, not a fault. The connection resumes when the receiver sends a window update.

Setting buffers by guesswork. The right window follows from the bandwidth-delay product of the path. Sizing receive buffers without knowing the bandwidth and latency is guessing at the number that actually caps throughput.

TCP WINDOW SIZE: THE DATA ALLOWED IN FLIGHTacknowledgedsent and confirmedthe window: in flightsent, not yet acknowledgednot yet sentwaits for roomthe window slides right as acknowledgments arriveMax throughput of one connection = window size / round-trip time. The window must cover bandwidth x RTT.The 16-bit field holds 65,535 bytes; the window scale option raises it to about a gigabyte.
The byte stream in three parts: acknowledged, the window in flight, and not yet sent. The window is the receiver's advertised limit and slides right as acknowledgments arrive. Throughput is capped at the window over the round-trip time.

ComparisonTCP window size, the essentials

CriterionDetail
What it limitsUnacknowledged data in flight
Set byThe receiver, in every segment
Header field size16 bits, 65,535 bytes maximum
With window scalingUp to about one gigabyte
StandardRFC 7323 for the scale option
Throughput capWindow size divided by round-trip time
Must coverThe bandwidth-delay product of the path

The two rows that explain most real problems are the throughput cap and the bandwidth-delay product: they are why a small window throttles a fast, high-latency link.

FAQFrequently asked questions

What is the TCP window size?

The amount of data a sender may have sent but not yet had acknowledged at any moment. The receiver advertises it in every segment, and the sender may send up to that much before waiting for acknowledgments. It is TCP's flow-control mechanism.

Who sets the TCP window size?

The receiver. It advertises, in the window field of every segment it sends, how many more bytes it is currently willing to accept, which reflects the free space in its buffer.

What is the maximum TCP window size?

The header field is 16 bits, so the raw maximum is 65,535 bytes. With the window scale option, the effective window can reach roughly a gigabyte.

What is TCP window scaling?

An option, defined in RFC 7323, that raises the window above the 65,535-byte limit by left-shifting the advertised value by up to 14 bits. It is negotiated during the three-way handshake and is needed for fast, high-latency links.

How does window size affect throughput?

The maximum throughput of one TCP connection is the window size divided by the round-trip time, because a sender can have only one window in flight per round trip. A window too small for the latency caps throughput below the link speed.

What is the bandwidth-delay product?

The link bandwidth multiplied by the round-trip time: the amount of data that can be in transit on the path at once. The window must be at least this large to keep the link full.

What is the difference between the receive window and the congestion window?

The receive window is advertised by the receiver for flow control, protecting it from being overrun. The congestion window is computed by the sender for congestion control, protecting the network. The sender uses the smaller of the two.

What does a TCP window size of zero mean?

That the receiver's buffer is full and it is telling the sender to stop sending. It is normal flow control, not an error. The sender resumes when the receiver advertises a non-zero window in an update.

Why is my transfer slow on a fast connection?

Often because the window is too small for the round-trip time, so a single connection is throttled by window over latency rather than by bandwidth. Missing window scaling on one end is a frequent cause.

Is the TCP window size the same as MSS?

No. The maximum segment size, tied to the MTU, is the largest single segment a TCP connection will send; the window size is how many bytes, across many segments, may be unacknowledged at once. One is per segment, the other is total in flight.

Where is the window size in the TCP header?

It is a dedicated 16-bit field in the TCP header, present in every segment. The window scale option, when used, is carried separately in the options and multiplies that field's value.

Does a bigger window always mean faster?

Only up to the bandwidth-delay product. Beyond the point where the window covers the path, a larger window adds no throughput and only more memory use; below it, the window is the throttle.

What is the TCP receive window?

The TCP receive window is the amount of data a receiver says it can accept before the sender must wait for an acknowledgment. It is advertised in every segment. When it falls to zero the sender stops, which in a packet capture points to a slow application on the receiving side, not to the network.

Read next · Protocols TCP vs UDP Why TCP has a window at all and UDP has none. Open this next10 min
Also worth reading
One packet a weekA short, illustrated explainer every Tuesday. No vendor pitches, unsubscribe in one click.