A practical look at TCP autotuning

Linux has grown its own send and receive buffers for years, and most of the advice about setting net.ipv4.tcp_rmem by hand is a decade out of date. Still, autotuning is not magic, and understanding where it stops helps when throughput on a long fat path quietly tops out.

What grows automatically

The receive buffer grows on its own: the kernel samples the connection's receive rate and expands the window up to the maximum you allow. Sending is the same story. So for ordinary connections you rarely need to touch anything — the defaults scale to a few megabytes.

sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem
# rmem = min default max
# wmem = min default max

Where it gives up

Autotuning bounds the window by what it has seen, which means it is slow to react to a path that suddenly opens up. On a link with a large bandwidth-delay product, a connection that stalls early can stay conservative for a long time. Raising the maximum is usually the useful knob; the minimum almost never matters.

The two settings that pay off

sysctl net.ipv4.tcp_mtu_probing=1
sysctl net.ipv4.tcp_congestion_control=bbr   # when available

Measure before and after

Buffer changes are easy to make and hard to attribute. Record throughput and retransmit rate for the same flow before and after, on the same path, at the same time of day. If both numbers do not move, revert — configuration you cannot explain is configuration you cannot debug later.

← Back to all notes