Skip to content

$ cat ./posts/network/tcp-tuning-myths.conf

-rw-r--r-- 1.9K #network #perf

TCP tuning myths

by chris · 2 min read · /network


There is a block of sysctl settings that has been copied between deployment repositories for fifteen years. Most of it was written for kernels that could not autotune, and a good half of it is now either the default or actively unhelpful.

1. Buffer sizes autotune

net.ipv4.tcp_rmem and tcp_wmem have sensible defaults and scale with the connection. Pinning them to a large fixed value does not make transfers faster; it makes every idle connection expensive and hides real backpressure. Leave them alone unless a measurement says otherwise.

2. What is still worth setting

# congestion control that handles loss without collapsing
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq

# accept queue deep enough for burst arrivals
net.core.somaxconn = 4096

# reuse sockets in TIME_WAIT for outgoing connections
net.ipv4.tcp_tw_reuse = 1

BBR plus fq is the one change that reliably shows up in a graph, particularly on paths with any loss. somaxconn matters only if the application also raises its own backlog — the smaller of the two wins, and most runtimes default to 128.

3. What to stop copying

  • tcp_tw_recycle — removed from the kernel years ago, and it broke NAT clients before that.
  • tcp_syncookies = 0 — the cookies cost nothing until you are under a SYN flood, at which point they are the reason you stay up.
  • Enormous netdev_max_backlog — usually papering over a single-queue NIC that wants RSS configured instead.

4. Measure the queue, not the setting

ss -tin state established | head
nstat -az TcpExtListenOverflows TcpExtListenDrops

Non-zero listen overflows are a real signal that the accept queue is short. Everything else is a hypothesis until one of these counters moves.

← cd .. fris@linux:~/blog$ man network