TCP tuning on Windows and macOS: autotuning and buffers
Windows and macOS both tune TCP buffers automatically, and on most machines the right move is to make sure that autotuning is switched on and leave it alone. This page shows how to check it on each system, and the few settings worth changing on fast servers and workstations.
Windows: receive window autotuning
Old versions of Windows used a fixed receive window of 65,535 bytes, which badly limits throughput on long paths. Current Windows versions use receive window autotuning, which lets the window grow per connection using the RFC 1323 window scale option. Microsoft documents five levels; the default is Normal.
| Level | Window scale factor | Behavior |
|---|---|---|
| Normal (default) | 8 | Window grows to suit almost all scenarios |
| Restricted | 4 | Grows beyond the default, limited in some scenarios |
| Highly Restricted | 2 | Grows beyond the default, very conservatively |
| Experimental | 14 | Grows to accommodate extreme scenarios |
| Disabled | none | Window stays at its default size |
With autotuning disabled, the starting window depends on link speed; Microsoft lists 64 KB for links from 100 Mbit/s to 10 Gbit/s. At 50 ms of round-trip time, 64 KB allows only about 65,535 × 8 ÷ 0.05 ≈ 10.5 Mbit/s per connection.
Check and fix it on Windows
Open Command Prompt as administrator:
netsh interface tcp show global
Look for the line Receive Window Auto-Tuning Level. If it says anything other than normal, an old "speed tweak" tool or a past troubleshooting step may have changed it. To restore the default:
netsh interface tcp set global autotuninglevel=normal
The same check in PowerShell, run as administrator:
Get-NetTCPSetting | Select SettingName,AutoTuningLevelLocal
Set-NetTCPSetting -AutoTuningLevelLocal Normal
The output lists several setting templates (Internet, Datacenter, Compat and their Custom versions); Windows picks one per connection. The netsh output also shows the Add-On Congestion Control Provider, and Get-NetTCPSetting | Select SettingName,CongestionProvider shows the algorithm each template uses.
Windows limits to know about
- Registry tweaks are obsolete. Microsoft lists
TcpWindowSizeamong registry settings that are no longer supported and are ignored, and from Windows Server 2019 the registry cannot be used to set the receive window size. - Some settings are read-only on Windows 10. Microsoft notes that on Windows 10 you cannot modify
CongestionProvider,InitialCongestionWindowMss,MinRtoMs,CwndRestart,DelayedAckTimeoutMsorAutomaticUseCustom. Windows Server 2016 and 2019 allow changes to custom and non-custom templates. - Offloads. Microsoft advises not using the deprecated TCP Chimney Offload and IPsec Task Offload. Ordinary checksum and large send offloads are usually beneficial.
- Window scaling needs the network's cooperation. Microsoft notes that some network devices do not handle the window scale option correctly; if transfers stay stuck near 64 KB per round trip, check firewalls and load balancers on the path.
To measure the result on Windows, use iperf 2, which is supported there; iperf3 is not officially supported on Windows. See iperf 2 vs iperf3.
macOS: autotuning and its limits
macOS has autotuned TCP buffers since Mac OS X 10.5. ESnet's fasterdata site gives three settings for Macs connected at 1 Gbit/s or faster that need high throughput on long paths:
| Setting | Default per ESnet | Suggested |
|---|---|---|
net.inet.tcp.autorcvbufmax | 4 MB | 33554432 (32 MiB) |
net.inet.tcp.autosndbufmax | 4 MB | 33554432 (32 MiB) |
net.inet.tcp.win_scale_factor | 3 | 8 |
A window scale factor of 3 multiplies the 65,535-byte base by 8, giving at most about 524 KB of advertised window; a factor of 8 multiplies by 256, giving about 16.8 MB.
Check and change it on macOS
sysctl net.inet.tcp.autorcvbufmax net.inet.tcp.autosndbufmax net.inet.tcp.win_scale_factor
sudo sysctl -w net.inet.tcp.autorcvbufmax=33554432
sudo sysctl -w net.inet.tcp.autosndbufmax=33554432
sudo sysctl -w net.inet.tcp.win_scale_factor=8
Changes made with sysctl -w last until the next restart. ESnet suggests putting them in /etc/sysctl.conf, and notes that if current macOS versions do not load that file at boot, a script or a launch daemon in /Library/LaunchDaemons can apply them instead. New window scale settings affect new connections only.
Not for every Mac. ESnet advises against these settings on Wi-Fi laptops and on machines connected at 100 Mbit/s or less, and recommends reverting them if you see instability or lower performance. On a typical home or office Mac, the defaults are fine and the access link is the limit.
Measuring on a Mac
iperf3 installs with Homebrew (brew install iperf3) and is officially supported on macOS. For a quick check of how a connection behaves under load, Apple's built-in networkQuality command reports responsiveness in round-trips per minute (RPM) as well as throughput:
networkQuality