20 August 2026 · 8 min read · recloud engineering
High-performance DNS for ISPs: anycast resolver design
Subscribers don't experience your network — they experience your resolver. Every page load starts with a lookup, so resolver latency is multiplied into everything a customer does, and resolver downtime looks identical to a total outage. Here is how we design DNS for operators who take that seriously.
Anycast first, hardware second
One resolver address, announced from every site via BGP, and the routing table delivers subscribers to the nearest healthy instance. The critical detail is health-coupled announcement: the route must exist only while the resolver actually answers. A small BGP speaker on each resolver host (ExaBGP, or FRR with a health script) withdraws the prefix the moment the daemon fails its own lookup test:
# exabgp health process (simplified)
while true; do
if dig +time=1 +tries=1 @127.0.0.1 health.check.internal >/dev/null; then
echo "announce route 203.0.113.53/32 next-hop self"
else
echo "withdraw route 203.0.113.53/32 next-hop self"
fi
sleep 2
done
With that in place, losing a site is a routing event, not an outage — subscribers re-converge to the next site inside your IGP/BGP timers without a single ticket.
Resolver software and the tuning that matters
Unbound and Knot Resolver are both excellent; what matters more is the handful of settings that dominate performance:
# unbound.conf — the settings that actually move the needle
num-threads: 16 # one per core
so-reuseport: yes # kernel spreads load across threads
msg-cache-size: 2g
rrset-cache-size: 4g
serve-expired: yes # answer stale while refreshing
serve-expired-ttl: 86400
prefetch: yes # refresh popular names before expiry
serve-expired deserves special mention: when an authoritative server is slow or unreachable, answering with slightly-stale data keeps your subscribers browsing through someone else's outage. Cache hit rate is your one number to watch — a healthy ISP resolver sits above 85%, and every point of hit rate is milliseconds off median page loads.
Capacity: measure QPS per subscriber, then multiply
Rule of thumb from our fleets: residential subscribers average 1.5–3 queries/second at peak per thousand subscribers... measured per-network, it varies with CPE behaviour and IoT density. Benchmark your own with dnsperf against a replayed capture, size each site to carry the whole base (anycast means any site can inherit everyone), and keep steady-state per-site load under 30%.
Encrypted DNS is now table stakes
Offer DoT (853) and DoH alongside Do53, on the same anycast addresses. Terminate TLS in the resolver itself where supported, or with a lightweight proxy in front. Watch connection counts, not just QPS — encrypted transports hold state, and a CPE population that suddenly adopts DoH changes your memory profile more than your CPU.
The monitoring that keeps you honest
- Latency quantiles per site (p50/p95/p99), exported from the resolver, not synthesised.
- Cache hit rate and SERVFAIL ratio — the two early warnings of upstream trouble.
- Route presence: alert when a site's anycast prefix is missing from the RIB longer than a restart takes.
- External vantage: RIPE Atlas probes resolving through your service from inside your own footprint.
DNS is the cheapest place in the whole network to buy subscriber happiness: a weekend of tuning routinely halves median resolution time. It's also a natural first workload for a bare-metal Kubernetes cluster, where rollouts and monitoring come with the platform.