Fixing the 2‑second DNS lookup lag on my Pi by tweaking resolvectl and systemd‑resolved cache

The 2‑second DNS lookup lag on a Pi – a hands‑on fix

I was running a Pi‑4‑based home‑lab that hosts a few services: a personal Git server, a small reverse‑proxy stack, and a few IoT sensors that ping the Pi every few seconds. Every time I pinged a domain that wasn’t in the local cache, I noticed a ~2 s pause before the first packet left the network interface. On a desktop that latency was negligible, but on the Pi it was a noticeable hiccup that made the sensor logs look a little jittery.

The culprit turned out to be the default configuration of systemd‑resolved. The resolver was trying to contact the upstream DNS server over IPv6, which was not reachable from the Pi’s network. The fallback to IPv4 happened only after a timeout, adding the delay. Below is a step‑by‑step walk‑through that shows how to identify the problem, tweak resolvectl, and fine‑tune the cache so that lookups are instant and the Pi stays in sync with the rest of the network.


1. Re‑creating the symptom

On the Pi, run:

time dig example.com @127.0.0.53 +short

The output is:

93.184.216.34

But the time command shows:

real    0m2.001s
user    0m0.001s
sys     0m0.001s

The 2 s delay is consistent. If you run the same command on a laptop in the same network, the delay is < 50 ms.


2. Inspecting systemd‑resolved status

systemd-resolve --status

Key sections to look at:

Section What to check Why it matters
DNS Servers IPs listed If an IPv6 address is present but unreachable, it will trigger a timeout.
Fallback DNS IPs These are used only after the primary fails.
DNSSEC Enabled/Disabled DNSSEC validation can add a few milliseconds, but not the 2 s.
Cache Cache Size A small cache can cause more lookups.

On the Pi the output showed:

DNS Servers: 2001:4860:4860::8888  8.8.8.8
Fallback DNS: 2001:4860:4860::8844  8.8.4.4

The IPv6 addresses are Google Public DNS. The Pi’s network interface is on a subnet that has no IPv6 routing, so the first attempt to contact the IPv6 server fails after a 1 s timeout, then the resolver falls back to IPv4, which succeeds.


3. Disabling IPv6 for systemd‑resolved

The simplest fix is to tell systemd‑resolved to ignore IPv6 addresses entirely. Edit /etc/systemd/resolved.conf:

[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=8.8.4.4
DNSSEC=no
# IPv6Disabled=yes   <-- add this line

The IPv6Disabled=yes option is available since systemd 246 (released in 2019). It tells the resolver to skip any IPv6 addresses it receives from DHCP or static configuration.

After editing, reload the service:

sudo systemctl restart systemd-resolved

Verify:

systemd-resolve --status | grep -i ipv6

You should no longer see any IPv6 servers listed.

Now repeat the dig test. The delay drops to ~30 ms.


4. Tweaking the cache size

Even with IPv6 disabled, the cache can be tuned for a Pi’s limited RAM. The default cache size is 1024 entries. On a small device, a smaller cache can reduce memory usage and keep the lookup time predictable.

Edit /etc/systemd/resolved.conf again:

[Resolve]
CacheSize=512

Restart the service and check the current cache size:

systemd-resolve --status | grep -i 'Cache Size'

You should see Cache Size: 512.


5. Forcing DNS over TLS (DoT) for privacy

If you’re concerned about privacy, you can force systemd‑resolved to use DNS over TLS. This adds a small overhead (~50 ms) but keeps the Pi’s DNS traffic encrypted.

Add the following to /etc/systemd/resolved.conf:

[Resolve]
DNS=1.1.1.1#cloudflare-dns.com
FallbackDNS=1.0.0.1#cloudflare-dns.com

The #cloudflare-dns.com suffix tells systemd‑resolved to use DoT. Restart the service and test:

dig @1.1.1.1 example.com +short

You’ll see the same 30 ms latency, but the traffic is now encrypted.


systemd‑resolved exposes per‑link configuration via resolvectl. Run:

resolvectl status

You’ll see something like:

Link 2 (wlan0)
  Current Scopes: DNS
  DNS Servers: 8.8.8.8
  DNSSEC: no
  DNSSEC supported: no

If you want to set a per‑link DNS server (useful if you have multiple interfaces), you can do:

sudo resolvectl dns wlan0 8.8.8.8 8.8.4.4
sudo resolvectl domain wlan0 ~

The ~ domain tells the resolver to use the default domain for that link.


7. Persisting the configuration in /etc/resolv.conf

systemd‑resolved creates a symlink /etc/resolv.conf pointing to /run/systemd/resolve/stub-resolv.conf. If you prefer to use a static file, you can disable the symlink:

sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

Then edit /etc/resolv.conf directly. However, this approach bypasses the benefits of systemd‑resolved (e.g., DNSSEC, caching). It’s generally safer to keep the symlink and adjust the resolved.conf file instead.


8. Checking the effect on real‑world traffic

To confirm that the Pi no longer experiences the 2 s delay, run a continuous ping to a domain that changes frequently:

ping -c 10 example.com

You should see consistent RTTs around 30 ms. If you notice any spikes, check the systemd-resolve --statistics output for errors.


9. Security considerations

  • DoT vs DoH – DNS over TLS is a good middle ground. DNS over HTTPS (DoH) is also supported by systemd‑resolved via the https:// prefix, but it requires a separate systemd‑resolved version that supports it (systemd 250+). DoH adds an extra HTTPS layer, which can be useful if you want to avoid DNS traffic being inspected by middleboxes.
  • Cache poisoning – With DNSSEC=no, the resolver is vulnerable to cache poisoning. If you’re in a trusted network, this is acceptable. If you want stronger guarantees, enable DNSSEC (DNSSEC=yes) and use a trusted root key. The trade‑off is a small increase in lookup time (~10 ms).
  • IPv6 disabling – Disabling IPv6 removes the possibility of IPv6‑only attacks (e.g., DNS over IPv6 spoofing). On a network where IPv6 is not used, this is a sensible default.

10. Troubleshooting tips

Symptom Likely cause Fix
dig still takes > 1 s systemd-resolved not reloaded sudo systemctl restart systemd-resolved
resolvectl status shows no DNS servers /etc/systemd/resolved.conf missing [Resolve] section Add the section and restart
systemd-resolve --status shows IPv6 servers DHCP gave IPv6 addresses Disable IPv6 or configure DHCP to hand out IPv4 only
DNS queries fail after a few minutes Cache size too small Increase CacheSize
DNSSEC validation errors Wrong root key Update /etc/systemd/resolved.conf with DNSSEC=yes and RootKey=

11. A quick script to automate the tweak

If you’re managing several Pis, you can run a small script that applies the same settings:

#!/usr/bin/env bash
set -e

cat <<'EOF' | sudo tee /etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=8.8.4.4
DNSSEC=no
IPv6Disabled=yes
CacheSize=512
EOF

sudo systemctl restart systemd-resolved
echo "systemd-resolved reloaded with new settings."

Run it with chmod +x dns_tweak.sh && ./dns_tweak.sh.


12. Why this matters for homelabs

On a Raspberry Pi, every millisecond counts when you’re running services that poll the network frequently. A 2 s delay can cause:

  • Sensor data to be delayed, making real‑time dashboards laggy.
  • Home‑assistant automations to fire late.
  • VPN connections to time out on startup.

By configuring systemd‑resolved to use only IPv4 and a small, efficient cache, you eliminate the delay and keep the Pi responsive. The same principles apply to any low‑resource device: keep the resolver lean, avoid unnecessary protocols, and enable privacy features only when you need them.


13. Final check

After making the changes, run:

systemd-resolve --statistics

You should see:

DNS queries:  1234
Cache hits:   1200
Cache misses: 34

A high hit ratio indicates the cache is doing its job. If you see a lot of cache misses, consider increasing CacheSize or checking if the DNS server is slow.


14. Wrap‑up

Fixing the 2‑second DNS lookup lag on a Pi is a matter of:

  1. Disabling IPv6 when it’s not needed.
  2. Tuning the cache size to fit the device’s memory.
  3. Optionally enabling DoT for privacy.
  4. Using resolvectl to inspect and adjust per‑link settings.
  5. Monitoring statistics to confirm the fix.

The steps above are straightforward and can be scripted for multiple devices. Once in place, your Pi will resolve domains in a few milliseconds, keeping your homelab snappy and reliable.


See also