Measure it first
Before changing anything, measure. Bufferbloat is invisible in a speed test: the speed is fine. What changes is latency under load, so the test is simple: ping something on the internet while a transfer fills the line.
On an idle line, a ping from the office PC to the server takes about 1.3 ms. Then:
- During an upload, the average ping is 713 ms, and the worst is over a second. The upload itself runs at the full 4.78 Mbit/s.
- During a download, the average is 400 ms, up to half a second, at 19.1 Mbit/s.
So one person's backup makes the whole office's internet respond like a satellite link. Note what doesn't help: Debian's router already uses fq_codel, a good modern queue, on its WAN interface. But its queue is empty, because the router can send far faster than the line. The queue that matters is in the modem.
Real-world tests show the same thing: run a speed test with a latency graph (several online tests report "latency under load" or a bufferbloat grade) and compare the idle and loaded numbers.
root@gw:~# cat /etc/debian_version; uname -r; dpkg-query -W iproute2 systemd; modinfo -F filename sch_cake ifb
13.7
6.12.115+deb13.1-amd64
iproute2 6.15.0-1
systemd 257.13-1~deb13u1
/lib/modules/6.12.115+deb13.1-amd64/kernel/net/sched/sch_cake.ko.xz
/lib/modules/6.12.115+deb13.1-amd64/kernel/drivers/net/ifb.ko.xz
root@gw:~# tc qdisc show dev ens4
qdisc fq_codel 0: root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 - Lines 2–3: Debian 13 with its own kernel, 6.12.
- Lines 6–7: CAKE and IFB are modules in Debian's kernel.
- Lines 9–10: Debian's default queue on the WAN: fq_codel. Good, but the queue isn't here.
root@modem:~# tc qdisc show dev eth1; tc qdisc show dev eth0
qdisc tbf 8003: root refcnt 17 rate 5Mbit burst 16Kb lat 1s
qdisc tbf 8004: root refcnt 17 rate 20Mbit burst 32Kb lat 500ms
root@client:~# ping -q -c 20 -i 0.2 198.51.100.10 | tail -2
20 packets transmitted, 20 received, 0% packet loss, time 3876ms
rtt min/avg/max/mdev = 0.495/1.274/2.259/0.548 ms
root@client:~# iperf3 -c 198.51.100.10 -t 20 > /tmp/up.txt & sleep 3; ping -q -c 75 -i 0.2 198.51.100.10 | tail -2; wait; grep receiver /tmp/up.txt
75 packets transmitted, 75 received, 0% packet loss, time 15011ms
rtt min/avg/max/mdev = 263.640/713.418/1029.841/260.968 ms, pipe 6
[ 5] 0.00-20.85 sec 11.9 MBytes 4.78 Mbits/sec receiver
root@client:~# iperf3 -c 198.51.100.10 -t 20 -R > /tmp/down.txt & sleep 3; ping -q -c 75 -i 0.2 198.51.100.10 | tail -2; wait; grep receiver /tmp/down.txt
75 packets transmitted, 75 received, 0% packet loss, time 14994ms
rtt min/avg/max/mdev = 193.852/399.697/512.181/84.718 ms, pipe 3
[ 5] 0.00-20.00 sec 45.5 MBytes 19.1 Mbits/sec receiver- Lines 1–3: The modem: tbf at 5 Mbit/s up and 20 down, holding up to a second and half a second of traffic.
- Lines 5–7: Idle: 1.3 ms on average.
- Lines 9–12: During an upload: 713 ms on average, over a second at worst.
- Lines 14–17: During a download: 400 ms on average.
Check your understanding
A speed test shows the office line runs at the full advertised speed, yet calls stutter whenever someone uploads. What do you measure?
- Latency under load: ping while the line is full.
- The speed test again, at a different time.
- Packet loss on an idle line.
- The router's CPU load.