On our Machines in fra (kernel 6.12.114-fly), the sysctls ask for fq and BBR:
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
eth0 itself still runs pfifo_fast, with tx_queue_len 1000. tc qdisc show dev eth0 lists pfifo_fast as the root qdisc on every Machine we checked.
The kernel only uses default_qdisc when a device gets its root qdisc. My guess is that init writes the sysctl after eth0 is already up, so the setting never reaches it. I can’t see init, so that part is a guess.
This cost us real latency. Our app is a WebSocket relay that sends one small packet to each of about 4,000 viewers every 200 ms, all at once. A 1,000-packet queue overflows on every burst. In a 5-minute load test, tc -s qdisc counted about 1.5 million dropped packets per relay. TCP only resends a dropped packet when a retransmit timer fires, so the slowest 1% of viewers waited 450 ms instead of 260 ms, and the worst waited about 1 s.
We now run tc qdisc replace dev eth0 root fq as root at startup, then drop to our app user. In five 5-minute runs since, the qdisc dropped nothing and the slowest 1% stayed between 255 and 270 ms.
Could init put fq on eth0 itself, for example by setting the sysctl before eth0 comes up? Machines would then match their own sysctl, and apps wouldn’t need iproute2 and a root start just for this.
An older wishlist thread asked for these defaults: Change net qdisc and tcp congestion control defaults