Debugging intermittent packet loss on home links
The complaint is always the same shape: "the internet is slow sometimes". It is intermittent, it clears up on its own, and by the time you sit down to measure it the problem is gone. Here is an order of investigation that converges faster than random poking.
Separate the three layers first
Before touching anything, establish which of these is failing:
- Link layer — the physical or wireless hop to the router.
- Path — the route from router to destination.
- Endpoint — the server or the client.
Run a continuous ping to three targets simultaneously: your gateway, a well-connected domestic address, and the far endpoint. The pattern of which one drops tells you the layer.
ping -i 1 192.168.1.1
ping -i 1 223.5.5.5
ping -i 1 1.1.1.1
Gateway drops but others are clean: local link. Gateway clean but the domestic target drops: upstream. Both clean but the far endpoint drops: that endpoint or its path.
Wireless is usually the answer
On WiFi, loss that appears under load but not at idle is almost always retransmission from a weak signal or channel contention. Two numbers decide it:
iw dev wlan0 station dump | grep -E "signal|tx retries|tx failed"
Signal around -70 dBm or worse, with a rising retry count, means the radio link is the problem and nothing above it matters. Changing channel or moving the access point fixes more of these than any router setting.
MTU and fragmentation
A specific and easily missed failure: small packets pass, large packets vanish. That is an MTU problem, usually from a tunnel or PPPoE hop that shrinks the usable payload without proper path MTU discovery.
ping -M do -s 1472 1.1.1.1 # 1472 + 28 = 1500
ping -M do -s 1400 1.1.1.1
If 1472 fails and 1400 succeeds, your path MTU is somewhere in between. Either fix the MTU on the offending interface or enable probing:
net.ipv4.tcp_mtu_probing = 1
Setting it to 2 makes it always-on rather than only after a black hole is detected, which helps on links that drop ICMP unreachables.
Distinguish loss from reordering
They feel identical to a user and have different causes. Reordering inflates RTT variance without dropping packets; loss shows up as retransmissions.
ss -tin state established | grep -E "retrans|reord"
High reord_seen with low retrans points at multipath or a load balancer hashing inconsistently. High retrans with clean reordering points at genuine loss.
When it is the congestion algorithm
Loss-based algorithms treat any loss as a congestion signal and halve the window, even when the loss came from a flaky radio hop rather than a full queue. On a lossy link this produces sawtooth throughput that looks like "the connection keeps stalling".
Switching to a delay-based algorithm often turns a 2 Mbit/s stuttering link into a stable 20 Mbit/s, on the same hardware, with no other change:
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
Keeping records
Intermittent problems are only solvable if you have history. A one-line cron job that appends a timestamped latency sample costs nothing and turns "it was bad yesterday evening" into a chart you can correlate with something:
* * * * * ping -c 5 -W 1 1.1.1.1 | tail -1 >> /var/log/latency.log
Rotate it or it will grow forever. The point is not precision — it is having any record at all of when the problem happened.