2026-04-11
家の回線が急に重くなったので切り分けた
症状
家の回線が急に重くなりました.
最初は Wi-Fi の調子が悪いだけだと思っていたのですが, 有線でも無線でも Web サイトの読み込みが重い. しかも完全に通信できないわけではなく, なんとなく待たされる感じです.
体感だけで判断すると ISP 側の混雑や Wi-Fi の電波強度を疑いたくなるのですが, 今回はそこが本質ではありませんでした. 結論から言うと, 帯域不足ではなく DNS と resolver 周りが主因でした.
最初に見たこと
最初に使っていたのは Arch Linux のノート PC です. まずは本当に Wi-Fi が悪いのかを見ました.
$ iw dev wlan0 link
SSID: <redacted>
freq: 2462.0
signal: -25 dBm
rx bitrate: 144.4 MBit/s MCS 15 short GI
tx bitrate: 144.4 MBit/s MCS 15 short GI
電波強度はかなり良く, ビットレートも極端に低いわけではありません. ただし 2.4GHz 接続だったので, ここは最初に疑いました.
次にルーターまでの遅延を確認しました.
$ ping -c 20 192.168.0.1
rtt min/avg/max/mdev = 7.074/9.368/14.874/1.658 ms
無線としては少し重いですが, これだけで「何もかもが遅い」説明には足りません.
計測して見えた差分
Web 側で何が遅いのかを curl のタイミングで見たところ, 面白い差が出ました.
$ curl -4 --http1.1 -o /dev/null -s -w 'host=github.com\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_starttransfer=%{time_starttransfer}\n' https://github.com
host=github.com
time_namelookup=8.043343
time_connect=8.072723
time_starttransfer=8.137182
$ curl -4 --http1.1 -o /dev/null -s -w 'host=youtube.com\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_starttransfer=%{time_starttransfer}\n' https://youtube.com
host=youtube.com
time_namelookup=8.052221
time_connect=8.069912
time_starttransfer=8.184691
一方で Cloudflare のダウンロードは普通に速く, 帯域そのものが死んでいる感じではありませんでした.
$ curl -4 -L -o /dev/null -s -w 'time_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_starttransfer=%{time_starttransfer}\nspeed_download=%{speed_download}\n' 'https://speed.cloudflare.com/__down?bytes=25000000'
time_namelookup=0.037463
time_connect=0.062800
time_starttransfer=0.149302
speed_download=11906888
speed_download=11906888 byte/s なので, ざっくり 95Mbps は出ています.
ここで重要だったのは, 遅いのが time_connect ではなく, その手前の time_namelookup に丸ごと乗っていることでした. つまり「Web が遅い」のではなく, 「名前解決に待たされている」状態です.
DNS を疑って確かめた
次に DNS をバイパスしてみました.
$ curl -4 --http1.1 --resolve www.google.com:443:142.251.152.119 -o /dev/null -s -w 'remote_ip=%{remote_ip}\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_appconnect=%{time_appconnect}\ntime_starttransfer=%{time_starttransfer}\n' https://www.google.com
remote_ip=142.251.152.119
time_namelookup=0.000009
time_connect=0.037608
time_appconnect=0.068008
time_starttransfer=0.168881
DNS を飛ばした瞬間に即時化したので, 原因はかなり絞れました.
さらに Node の dns.Resolver で DNS サーバーを直接叩くと, ISP 提供 DNS の一部で明確にタイムアウトが出ました.
ISP DNS #1 -> www.google.com: TIMEOUT (3000ms)
ISP DNS #2 -> www.google.com: TIMEOUT (3000ms)
1.1.1.1 -> www.google.com: 27.1ms
8.8.8.8 -> www.google.com: 30.2ms
この時点で, 回線全体が遅いのではなく, ISP 配布 DNS の一部問い合わせが不安定だと判断しました.
もう一段深かった原因
DNS を公開 DNS に変えただけでは, Linux 側でまだ 5秒 前後待つパターンが残りました. ここで効いたのが single-request と single-request-reopen です.
$ curl -4 --http1.1 -o /dev/null -s -w 'host=github.com\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_starttransfer=%{time_starttransfer}\n' https://github.com
host=github.com
time_namelookup=5.037126
time_connect=5.062832
time_starttransfer=5.127349
$ RES_OPTIONS='single-request-reopen' curl -4 --http1.1 -o /dev/null -s -w 'host=github.com\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_starttransfer=%{time_starttransfer}\n' https://github.com
host=github.com
time_namelookup=0.033803
time_connect=0.062845
time_starttransfer=0.138969
つまり今回は 2 段階で問題がありました.
- ISP 提供 DNS の一部が不安定
- resolver の
A/AAAA同時問い合わせまわりと相性が悪く, 追加の待ちが乗る
「家の回線が遅い」という見え方でしたが, 実際には DNS と resolver の組み合わせで Web だけ遅く見えていました.
実際に効いた対処
Linux 側では公開 DNS を設定し, resolv.conf に single-request single-request-reopen を入れたところ, 計測値がここまで戻りました.
$ curl -4 --http1.1 -o /dev/null -s -w 'host=github.com\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_starttransfer=%{time_starttransfer}\n' https://github.com
host=github.com
time_namelookup=0.034294
time_connect=0.066941
time_starttransfer=0.142951
$ curl -4 --http1.1 -o /dev/null -s -w 'host=youtube.com\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_starttransfer=%{time_starttransfer}\n' https://youtube.com
host=youtube.com
time_namelookup=0.033483
time_connect=0.066065
time_starttransfer=0.194561
家庭内の別の Windows PC でも同じ方向で確認しました. こちらは有線接続で, DNS を 1.1.1.1 と 8.8.8.8 に変えた時点で改善しました.
PS> Get-DnsClientServerAddress -InterfaceAlias "イーサネット 3"
InterfaceAlias Interface Address ServerAddresses
-------------- --------- ------- ---------------
イーサネット 3 7 IPv4 {1.1.1.1, 8.8.8.8}
PS> curl.exe -4 -o NUL -s -w "lookup=%{time_namelookup} connect=%{time_connect} start=%{time_starttransfer}`n" https://github.com
lookup=0.029849 connect=0.050341 start=0.122651
ルーターまでの ping も正常でした.
PS> ping 192.168.0.1 -n 20
最小 = 0ms、最大 = 1ms、平均 = 0ms
今回の学び
今回の件で一番大きかったのは, 体感の「重い」を帯域不足と決めつけなかったことです.
特に効いたのは次の 3 つでした.
pingで PC とルーター間の問題を先に切るcurlのtime_namelookup,time_connect,time_starttransferを見る--resolveや DNS 直叩きで, 名前解決をバイパスした時の差分を見る
Wi-Fi の軽い遅延と DNS 問題が同時にあると, つい「無線が悪い」「ISP が重い」で止まりがちです. 今回はログを細かく見たことで, どこで待たされているかを切り分けられました.
また同じことが起きたら, 自分はまず次の 3 つから見ます.
ping 192.168.0.1
curl -4 -o /dev/null -s -w 'lookup=%{time_namelookup} connect=%{time_connect} start=%{time_starttransfer}\n' https://github.com
curl -4 --resolve www.google.com:443:<IP> -o /dev/null -s -w 'lookup=%{time_namelookup} connect=%{time_connect} start=%{time_starttransfer}\n' https://www.google.com