How to find out what is actually breaking your home wifi

Our TV kept buffering while the mesh app insisted everything was fine. Six days of continuous measurement found one failing node, after four wrong theories. Here is the method, which transfers to any home network.

Engineering#networking#debugging#monitoring#wifi#home-network

Our TV kept buffering in the evenings. The mesh app said the network was healthy. It took six days of continuous measurement to find the actual cause: a single mesh node whose management processor was intermittently locking up while its network switch carried on forwarding traffic perfectly. Along the way we killed four confident theories, including one we had already written up as "confirmed".

If you have a home network that misbehaves in ways your router app cannot see, the method below transfers directly. None of it needs special hardware. It is all ping, a text file, and the discipline to stop guessing.

Why the router app is useless for this

Mesh apps show you a topology diagram and a green tick. They are built to confirm that the mesh exists, not to tell you it wobbled for ninety seconds while someone was watching a film. Our app showed nothing at all across the entire investigation.

Worse, the device logs were a rolling buffer holding about three and a half hours. By the time we thought to export them the next morning, the evening we cared about had already scrolled away. If your kit has a log, export it the same evening or accept it is gone.

Rule one: measure continuously, and make sure the measurement survives

The first monitor we wrote logged latency to every node every thirty seconds. It worked, and it died at 18:41 when the laptop went to sleep, which was roughly an hour before the fault we were trying to catch.

That is the whole lesson. A monitor that stops is worse than no monitor, because a gap in the data looks exactly like a quiet night:

nohup caffeinate -i ~/netmon/netmon.sh > ~/netmon/netmon.log 2>&1 &

caffeinate -i keeps macOS awake while the script runs. It does not survive the lid closing, so leave it open. Before trusting any quiet period, verify coverage by checking the gaps between consecutive timestamps rather than eyeballing the file.

Second refinement: log a snapshot at the moment things break. Our monitor watched one critical device, and on its first bad sample it dumped a full diagnostic to a capture file. Who was reachable, a traceroute, the ARP table. That snapshot is what eventually solved the case, because it recorded the state of six devices during a fault that lasted under two minutes at half past one in the afternoon while nobody was home.

Rule two: pick a control device

The single most useful question in any network fault is not "what broke" but "what stayed up while it broke".

That only works if you have chosen your comparisons deliberately. Our network ran a powerline link between two rooms, so we made sure to monitor:

  • A device on the near side of the powerline link
  • A device on the far side of it, wired directly to the adapter
  • The device we suspected, sitting between them

Each has a different failure signature. If everything on the far side fails together, the link is at fault. If a device wired to the adapter stays healthy while the node next to it dies, the link is fine and the node is not.

Write the decision table out before the fault happens, while you are calm. Ours lived in a project file and turned a chaotic evening into a lookup.

Rule three: identity is the MAC address, not the IP

This is the mistake we made, and it cost a day and a wrong conclusion.

The monitor pinged devices by IP address. DHCP leases on a busy home network reshuffle constantly. By the next morning, the address we had been recording as "the TV" was answering for a speaker, and the address recorded as "the soundbar" belonged to something else entirely.

We had written up a confident conclusion resting on those two devices failing together. It had to be retracted. The fix is to treat the MAC address as the identity and re-resolve the address on every cycle:

resolve() { # mac -> current ip
  arp -an | grep -v incomplete | awk -v want="$1" '
    { ip=$2; gsub(/[()]/,"",ip); m=tolower($4)
      n=split(m,o,":"); s=""
      for(i=1;i<=n;i++){ if(length(o[i])==1) o[i]="0" o[i]
                         s=s (i>1?":":"") o[i] }
      if (s==want) { print ip; exit } }'
}

The zero padding matters because arp prints 4:b9:e3 where the vendor sticker says 04:b9:e3. Write the resolved mapping to a file each cycle so any later analysis can check which device actually held an address at the time.

One more portability note: macOS ships bash 3.2, which has no associative arrays. A declare -A fails silently and collapses every measurement onto one value, which shows up as identical numbers across every column.

Rule four: let the person who lives there argue back

We had built a detailed case against the powerline link. Latency that swung between 5 ms and 1,150 ms on consecutive seconds, no correlation with packet size, both far-side devices failing together.

The person who actually lives in the house pointed out two things. The trouble predated the powerline installation, so it could not be the original cause. And it worsened when somebody walked into the room, which is a strange trigger for an electrical fault.

We had an answer for the second point: people switch lights on when they enter, and lighting is a classic source of mains interference. The reply killed it. The bulbs run on a dusk schedule, and this was happening in daylight.

That reframing is what solved it. Household knowledge beats instrumentation for generating hypotheses, and instrumentation beats intuition for testing them. You need both.

What it turned out to be

The capture file from a daytime fault, with every identity verified by MAC:

router        1.32 ms    OK
node (hall)   4.49 ms    OK
node (bed)    1.25 ms    OK
node (living) 100% LOSS  FAIL
speaker       2.39 ms    OK   <- past the powerline link
TV            3.08 ms    OK   <- wired into the failing node

The speaker sits on the far side of the powerline link and answered in 2.4 ms, so the link was carrying traffic perfectly. The TV is wired into the failing node and answered in 3.1 ms, so that node's switch was still forwarding. Only its management processor stopped responding.

That single row explains everything the other theories could not, including why a person arriving with a phone could stall a TV connected by cable.

What this saves you

The node in question is 2017-era hardware running about twenty clients. The fix is to replace that one unit, not the whole mesh, and specifically not the router, which averaged 3.71 ms across 5,828 samples and stayed healthy throughout every single fault.

Without measurement, the instinct is to replace the router, because it feels like the thing in charge. That would have cost real money and fixed nothing.

Measure first. Pick controls deliberately. Track devices by MAC. Then buy exactly one thing.

Enjoyed this? Get Hurricane Signal

Field notes on building real things with LLMs. Occasional, practical, no hype.