How To Debug Issue with Slow DNS

If the DNS take more than 30 millisecond to resolve, you’ll notice some slowness in the browsing, even though the download speed are normal. For download speed, we can check using iperf, wget or curl, and using website like speedtest.net, fast.com or speed.cloudflare.com

From Linux we can try to debug this issue with dig, let’s try to check the current DNS resolution speed

$ dig yahoo.com 
 
; <<>> DiG 9.18.33 <<>> yahoo.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10911
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
 
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;yahoo.com.			IN	A
 
;; ANSWER SECTION:
yahoo.com.		1324	IN	A	74.6.231.20
yahoo.com.		1324	IN	A	74.6.143.25
yahoo.com.		1324	IN	A	98.137.11.164
yahoo.com.		1324	IN	A	98.137.11.163
yahoo.com.		1324	IN	A	74.6.231.21
yahoo.com.		1324	IN	A	74.6.143.26
 
;; Query time: 83 msec
;; SERVER: 192.168.88.15#53(192.168.88.15) (UDP)
;; WHEN: Sat Mar 01 10:19:56 WIB 2025
;; MSG SIZE  rcvd: 134

Check the line Query time: 83 msec, the server 192.168.88.15 which is my Pi-hole DNS server hosted on my LAN. First check the latency between your computer to the DNS server

$ ping -c3 192.168.88.15
PING 192.168.88.15 (192.168.88.15) 56(84) bytes of data.
64 bytes from 192.168.88.15: icmp_seq=1 ttl=64 time=0.336 ms
64 bytes from 192.168.88.15: icmp_seq=2 ttl=64 time=0.283 ms
64 bytes from 192.168.88.15: icmp_seq=3 ttl=64 time=0.241 ms
 
--- 192.168.88.15 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2084ms
rtt min/avg/max/mdev = 0.241/0.286/0.336/0.038 ms

those result rule out the cable or wifi issue between computer and DNS Server. If ping doesn’t work, use mtr, for example

$ mtr -r -w -z 1.1.1.1
Start: 2025-03-01T10:34:06+01200
HOST: siding                                       Loss%   Snt   Last   Avg  Best  Wrst StDev
  1. AS???    _gateway                              0.0%    10    0.3   0.4   0.3   0.5   0.1
  2. AS???    192.168.100.1                         0.0%    10    0.8   0.8   0.7   1.5   0.2
  3. AS???    10.247.255.254                        0.0%    10    5.4   4.9   4.4   5.4   0.3
  4. AS???    10.24.67.71                           0.0%    10   14.3  21.6   8.4  51.7  14.3
  5. AS???                                         10.0%    10    5.5   4.4   4.1   5.5   0.4
  6. AS???    ???                                  100.0    10    0.0   0.0   0.0   0.0   0.0
  7. AS???                                          0.0%    10    4.9   4.7   4.5   5.1   0.2
  8. AS???                                          0.0%    10   16.5  16.3  15.9  16.5   0.2
  9. AS???                                          0.0%    10   16.8  28.4  16.4  91.9  23.5
 10. AS???                                          0.0%    10   25.8  17.8  16.4  25.8   2.9
 11. AS13335  one.one.one.one                       0.0%    10   16.2  16.4  16.2  16.6   0.2

Verify Using Different DNS Server

Try to query the domain using public DNS server like 1.1.1.1, 8.8.8.8 or 9.9.9.9

$ dig yahoo.com @1.1.1.1 | grep 'Query time:'
;; Query time: 16 msec
$ dig yahoo.com @8.8.8.8 | grep 'Query time:'
;; Query time: 16 msec
$ dig yahoo.com @9.9.9.9 | grep 'Query time:'
;; Query time: 18 msec

based on that information, we can query faster using internet compare via Pi-hole. In this case the easiest solution is to switch the DNS, to any of those DNS server.

For most of the people who didn’t manage their own DNS server, replace DNS should be more than enough, but if you manage your own Pihole or any other DNS solution, we need to find out the real reason 😀

Check DNS Query Logs

Pihole comes with dnsmasq to cache the DNS, so let’s check the logs

tail -f /var/log/pihole.log

upon checking the random domain using dig, I notice that cached DNS resolved slower compare to un-cached DNS result

$ dig example.com @192.168.88.15

the logs lines for those query

tail -f /var/log/pihole.log
Mar  1 10:43:00 dnsmasq[1053]: query[A] example.com from 192.168.88.2
Mar  1 10:43:00 dnsmasq[1053]: forwarded example.com to 127.0.0.1#5300
Mar  1 10:43:00 dnsmasq[1053]: reply example.com is 96.7.128.175
Mar  1 10:43:00 dnsmasq[1053]: reply example.com is 23.215.0.138
Mar  1 10:43:00 dnsmasq[1053]: reply example.com is 96.7.128.198
Mar  1 10:43:00 dnsmasq[1053]: reply example.com is 23.215.0.136
Mar  1 10:43:00 dnsmasq[1053]: reply example.com is 23.192.228.80
Mar  1 10:43:00 dnsmasq[1053]: reply example.com is 23.192.228.84
 
Mar  1 10:43:07 dnsmasq[1053]: query[A] example.com from 192.168.88.2
Mar  1 10:43:07 dnsmasq[1053]: cached example.com is 96.7.128.175
Mar  1 10:43:07 dnsmasq[1053]: cached example.com is 23.215.0.138
Mar  1 10:43:07 dnsmasq[1053]: cached example.com is 96.7.128.198
Mar  1 10:43:07 dnsmasq[1053]: cached example.com is 23.215.0.136
Mar  1 10:43:07 dnsmasq[1053]: cached example.com is 23.192.228.80
Mar  1 10:43:07 dnsmasq[1053]: cached example.com is 23.192.228.84

first query from dig takes 30ms, the second query (cached), takes 90ms.

So I take assumption that this due dnsmasq cache full, take a look at the config /etc/dnsmasq.d/01-pihole.conf

cache-size=10000
server=127.0.0.1#5300

cache size only 10000, the Pihole never restared for last 3 months, so that a good guess the reason this issue happening. So I add more 0 for the cache-size

cache-size=1000000
server=127.0.0.1#5300

restart the pihole

# restart pihole
pihole restartdns
# or clean the cache
pihole restartdns reload

Let’s run another dig command

$ dig google.co.uk  @192.168.88.15
;; Query time: 23 msec
$ dig google.co.uk  @192.168.88.15
;; Query time: 0 msec

the first query take 23 millisecond then the next one 0 millisecond because it’s cached as expected.

To do more test, download the top 50000 domain from https://radar.cloudflare.com/domains, and run the dig againts the domain list.

Leave a Comment