Ray

Why your transfer stalls at 3% packet loss

2026-09-18

Every few months someone sends me a bandwidth test that looks fine on paper and terrible in practice: 300 Mbps on a speed test, but a single large download crawls. The usual culprit is not bandwidth at all — it is the interaction between round-trip time, loss, and the congestion controller.

The arithmetic nobody enjoys

A classic loss-based controller treats a dropped packet as a congestion signal and cuts its window hard. On a long path with even 2–3% loss, that means the window is constantly collapsing right after it grows. Throughput ends up proportional to MSS / (RTT * sqrt(p)). Double the RTT and you halve the ceiling; double the loss and it gets worse again.

Bufferbloat makes it look like loss

A queue that is too deep converts loss into delay: nothing drops, but every packet sits in a buffer for hundreds of milliseconds, and the sender cannot tell the difference. An AQM such as fq_codel on the bottleneck link usually does more for perceived responsiveness than any amount of extra bandwidth.

What actually helped

Filed under: transport, latency.