Speedtest your DNS resolver | Benchmarking with DNSGauge
DNS is a hoot. After a deep dive into DNS-based adblocking tech last year, I wanted to get a better sense of the performance landscape for DNS resolvers. DNS is often the first step in loading a website or app, so it can have a big impact on overall speed.
DNSgauge is a quick and easy command-line tool to benchmark your DNS resolver. I ran a comprehensive test of 8 popular DNS providers over both DNS-over-HTTPS (DoH) and traditional UDP to see which is fastest in real-world conditions.
What really matters when choosing a DNS resolver is the average latency (p50) and the tail latency (p95) for your location. I also looked at success rates and jitter to get a full picture of performance. The TLDR is that for secure DoH requests, the popular resolvers Cloudflare and Quad9 are neck-and-neck with the lowest latency. For traditional UDP, NextDNS and Quad9 lead the pack.
This tool tests the following DNS resolvers:
| Provider | Protocol | Target |
|---|---|---|
| Cloudflare | UDP | 1.1.1.1 |
| Cloudflare | DoH | https://cloudflare-dns.com/dns-query |
| UDP | 8.8.8.8 |
|
| DoH | https://dns.google/dns-query |
|
| NextDNS | UDP | 45.90.28.0 |
| NextDNS | UDP | 45.90.30.0 |
| NextDNS | DoH | https://dns.nextdns.io |
| Quad9 | UDP | 9.9.9.9 |
| Quad9 | DoH | https://dns.quad9.net/dns-query |
| Quad9-ECS | DoH | https://dns11.quad9.net/dns-query |
| Mullvad | UDP | 194.242.2.2 |
| Mullvad | DoH | https://dns.mullvad.net/dns-query |
| AdGuard | UDP | 94.140.14.14 |
| AdGuard | DoH | https://dns.adguard.com/dns-query |
| LibreDNS | DoH | https://doh.libredns.gr/dns-query |
| OpenDNS | UDP | 208.67.222.222 |
Note: NextDNS DoH often requires a config-specific path, so https://dns.nextdns.io may need customization with --doh.
Quick Start: Try It Yourself
# Install dnsgauge via Homebrew
brew tap themorgantown/dnsgauge
brew install dnsgauge
# Run a quick comparison (takes ~30 seconds)
dnsgauge --doh-only --domains 10
# Run the full benchmark I used for this post
dnsgauge --doh-only --comprehensive --mode warm --passes 4 --domains 21 --qtypes A,AAAA,HTTPS --timeout 2.5
Test Environment
| Setting | Value |
|---|---|
| Location | Catskill Mountains, USA |
| Connection | Home Wifi |
| Date | February 2, 2026 |
| Tool | dnsgauge 1.1.0 |
| Domains tested | 21 popular sites (google.com, amazon.com, etc.) |
| Record types | A, AAAA, HTTPS |
| Mode | Warm (connection reuse enabled, simulates real browsing) |
Results: DNS-over-HTTPS (DoH)
DoH encrypts your DNS queries over HTTPS—this is what modern browsers use by default. I ran 4 passes with warm mode to simulate real browsing with HTTP/2 connection reuse.
DoH Latency Comparison
| Rank | Provider | p50 (ms) | p95 (ms) | Success | Jitter |
|---|---|---|---|---|---|
| 1 | Quad9 | 27 | 41 | 99% | 10ms |
| 2 | Cloudflare | 27 | 41 | 100% | 10ms |
| 3 | Quad9-ECS | 26 | 52 | 99% | 17ms |
| 4 | NextDNS | 28 | 54 | 100% | 21ms |
| 5 | 37 | 80 | 100% | 18ms | |
| 6 | LibreDNS | 121 | 153 | 100% | 40ms |
| 7 | AdGuard | 105 | 196 | 100% | 38ms |
| 8 | Mullvad | 262 | 353 | 100% | 71ms |
DoH Latency Chart
p50 Latency (ms) - Lower is better
─────────────────────────────────────────────────────────────
Quad9 ████████████████████████████ 27ms
Cloudflare ████████████████████████████ 27ms
Quad9-ECS ███████████████████████████ 26ms
NextDNS █████████████████████████████ 28ms
Google ██████████████████████████████████████ 37ms
AdGuard █████████████████████████████████████████████████████████████████████████████████████████████████████████ 105ms
LibreDNS █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ 121ms
Mullvad ██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ 262ms
Winner (best overall): Cloudflare (tied fastest p50/p95 with Quad9, and 100% success in this run).
Note: Quad9-ECS had the lowest p50 (26ms) but a worse p95 (52ms) and 99% success.
Results: Plain UDP DNS
For comparison, here’s how the resolvers perform over traditional UDP port 53. This is faster but unencrypted.
UDP Latency Comparison
| Rank | Provider | Endpoint | p50 (ms) | p95 (ms) | Success | Jitter |
|---|---|---|---|---|---|---|
| 1 | NextDNS | 45.90.28.0 | 9 | 11 | 100% | 2ms |
| 2 | Quad9 | 9.9.9.9 | 9 | 12 | 100% | 2ms |
| 3 | OpenDNS | 208.67.222.222 | 9 | 13 | 100% | 2ms |
| 4 | AdGuard | 94.140.14.14 | 9 | 14 | 100% | 2ms |
| 5 | Mullvad | 194.242.2.2 | 10 | 17 | 100% | 3ms |
| 6 | 8.8.8.8 | 10 | 16 | 100% | 3ms | |
| 7 | NextDNS | 45.90.30.0 | 9 | 13 | 100% | 11ms |
| 8 | Cloudflare | 1.1.1.1 | 12 | 47 | 100% | 93ms |
UDP Latency Chart
p50 Latency (ms) - Lower is better
─────────────────────────────────────────────────────────────
NextDNS (28.0) █████████ 9ms
Quad9 █████████ 9ms
OpenDNS █████████ 9ms
AdGuard █████████ 9ms
Google ██████████ 10ms
Mullvad ██████████ 10ms
Cloudflare ████████████ 12ms
Winner: NextDNS (9ms p50 with rock-solid 2ms jitter)
Surprise: Cloudflare’s UDP had high jitter (93ms) and a much higher p95 (47ms). This can happen due to local network variability and routing changes; rerun a few times to see if it persists.
What Does This Mean for 1,000 Domains/Day?
A typical power user might resolve ~1,000 unique domains daily (browsing, apps, background services). Let’s calculate the cumulative “waiting on DNS” time.
Important: a “domain” is not the same as a “DNS query.” Depending on the app and network, each domain might trigger:
- 1 lookup (lower bound, e.g., one A or AAAA lookup)
- 2 lookups (common: A + AAAA)
- 3 lookups (common in modern stacks: A + AAAA + HTTPS)
So below I show a range for 1,000 unique domains/day.
DoH: Cloudflare vs NextDNS
| Metric | Cloudflare | NextDNS | Δ (difference) |
|---|---|---|---|
| p50 | 27ms | 28ms | +1ms |
| p95 | 41ms | 54ms | +13ms |
Daily impact at 1,000 domains (range depends on lookups/domain):
| Scenario | Extra wait with NextDNS vs Cloudflare |
|---|---|
| Median-ish (p50) | ~1–3 seconds/day (1ms × 1,000 × 1–3 lookups) |
| Tail-heavy (p95) | ~13–39 seconds/day (13ms × 1,000 × 1–3 lookups) |
UDP: NextDNS vs Cloudflare
| Metric | NextDNS | Cloudflare | Δ (difference) |
|---|---|---|---|
| p50 | 9ms | 12ms | +3ms |
| p95 | 11ms | 47ms | +36ms |
Daily impact at 1,000 domains (UDP run used A+AAAA; range depends on lookups/domain):
| Scenario | Extra wait with Cloudflare vs NextDNS |
|---|---|
| Median-ish (p50) | ~3–6 seconds/day (3ms × 1,000 × 1–2 lookups) |
| Tail-heavy (p95) | ~36–72 seconds/day (36ms × 1,000 × 1–2 lookups) |
Recommendations
For Speed Alone
- DoH: Use Cloudflare or Quad9 (27ms p50)
- UDP: Use NextDNS or Quad9 (9ms p50)
For Privacy + Speed
- NextDNS offers ad/tracker blocking with competitive latency (28ms DoH, 9ms UDP)
- Quad9 blocks malware domains with top-tier speed
For Maximum Privacy
- Mullvad is slowest (262ms DoH) but pairs with their VPN for no-logging guarantees
Try It Yourself
I built dnsgauge so anyone can test their DNS resolver. It’s a simple command-line tool that runs on macOS and Linux.
# Install via Homebrew
brew tap themorgantown/dnsgauge
brew install dnsgauge
# Run a quick 30-second test
dnsgauge --domains 10
# Or Linux
git clone https://github.com/themorgantown/homebrew-dnsgauge.git
cd homebrew-dnsgauge
pipx install .
Technical Details
Test Environment & Methodology
Test Setup:
- Location: Catskill Mountains, USA
- Connection: Home Wifi
- Date: February 2, 2026
- Tool: dnsgauge 1.1.0
- Domains tested: 21 popular sites (google.com, amazon.com, etc.)
DoH Test:
- Record types: A, AAAA, HTTPS
- Mode: Warm (connection reuse enabled via HTTP/2)
- Passes: 4 (first pass for warmup, last 3 measured)
- Command:
dnsgauge --doh-only --comprehensive --mode warm --passes 4 --domains 21 --qtypes A,AAAA,HTTPS --timeout 2.5
UDP Test:
- Record types: A, AAAA
- Mode: Mixed
- Passes: 2
- EDNS0 payload: 1232 bytes (modern standard to avoid fragmentation)
Scoring:
- Success rate (most important)
- p95 tail latency (consistency matters)
- p50 median latency (typical performance)
- Jitter (variance in response time)
Limitations:
- Results vary by location and ISP routing
- Fixed domain list (21 popular sites)
- Single test run per configuration
Full DoH Results (All 8 Providers)
| Rank | Provider | p50 (ms) | p95 (ms) | Success | Jitter |
|---|---|---|---|---|---|
| 1 | Cloudflare | 27 | 41 | 100% | 10ms |
| 2 | Quad9 | 27 | 41 | 99% | 10ms |
| 3 | Quad9-ECS | 26 | 52 | 99% | 17ms |
| 4 | NextDNS | 28 | 54 | 100% | 21ms |
| 5 | 37 | 80 | 100% | 18ms | |
| 6 | LibreDNS | 121 | 153 | 100% | 40ms |
| 7 | AdGuard | 105 | 196 | 100% | 38ms |
| 8 | Mullvad | 262 | 353 | 100% | 71ms |
Full UDP Results (Top 8 Providers)
| Rank | Provider | Endpoint | p50 (ms) | p95 (ms) | Success | Jitter |
|---|---|---|---|---|---|---|
| 1 | NextDNS | 45.90.28.0 | 9 | 11 | 100% | 2ms |
| 2 | Quad9 | 9.9.9.9 | 9 | 12 | 100% | 2ms |
| 3 | OpenDNS | 208.67.222.222 | 9 | 13 | 100% | 2ms |
| 4 | AdGuard | 94.140.14.14 | 9 | 14 | 100% | 2ms |
| 5 | Mullvad | 194.242.2.2 | 10 | 17 | 100% | 3ms |
| 6 | 8.8.8.8 | 10 | 16 | 100% | 3ms | |
| 7 | NextDNS | 45.90.30.0 | 9 | 13 | 100% | 11ms |
| 8 | Cloudflare | 1.1.1.1 | 12 | 47 | 100% | 93ms |
Note: Cloudflare’s UDP had unusually high jitter (93ms) in this test run. Network variability happens—retest to confirm.
Raw Output Tables
DoH Warm Mode:
Run: mode=warm, passes=4, qtypes=A/AAAA/HTTPS, domains=21, servers=8, timeout=2.5s, edns_payload=1232, DoH_keepalive=on
Rank Score Provider Proto Endpoint Mode QTypes N Success p50 p95 Avg Jitter Timeout NX SF HTTPerr ParseErr OtherErr Trunc TCPfb RespKB_p95 HTTPver Reuse~
---- ----- ---------- ----- ------------------------------------ ---- ------------ --- ------- --- --- --- ------ ------- -- -- ------- -------- -------- ----- ----- ---------- ------- ------
1 141.7 Quad9 DoH https://dns.quad9.net/dns-query warm A/AAAA/HTTPS 189 99% 27 41 29 10 0% 0% 0% 0% 0% 1% — — 0.1 HTTP/2 96%
2 141.4 Cloudflare DoH https://cloudflare-dns.com/dns-query warm A/AAAA/HTTPS 189 100% 27 41 29 10 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 96%
3 129.8 Quad9-ECS DoH https://dns11.quad9.net/dns-query warm A/AAAA/HTTPS 189 99% 26 52 31 17 0% 0% 0% 0% 0% 1% — — 0.1 HTTP/2 96%
4 127.0 NextDNS DoH https://dns.nextdns.io warm A/AAAA/HTTPS 189 100% 28 54 33 21 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 96%
5 118.1 Google DoH https://dns.google/dns-query warm A/AAAA/HTTPS 189 100% 37 80 42 18 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 96%
6 090.8 LibreDNS DoH https://doh.libredns.gr/dns-query warm A/AAAA/HTTPS 189 100% 121 153 130 40 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 96%
7 089.4 AdGuard DoH https://dns.adguard.com/dns-query warm A/AAAA/HTTPS 189 100% 105 196 116 38 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 96%
8 076.2 Mullvad DoH https://dns.mullvad.net/dns-query warm A/AAAA/HTTPS 189 100% 262 353 283 71 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 96%
UDP Mixed Mode:
Run: mode=mixed, passes=2, qtypes=A/AAAA, domains=21, servers=16, timeout=2.5s, edns_payload=1232, DoH_keepalive=on
Rank Score Provider Proto Endpoint Mode QTypes N Success p50 p95 Avg Jitter Timeout NX SF HTTPerr ParseErr OtherErr Trunc TCPfb RespKB_p95 HTTPver Reuse~
---- ----- -------------------- ----- ------------------------------------ ----- ------ -- ------- --- --- --- ------ ------- -- -- ------- -------- -------- ----- ----- ---------- ------- ------
1 200.7 NextDNS UDP 45.90.28.0 mixed A/AAAA 84 100% 9 11 9 2 0% 0% 0% — — 0% 0% 0% 0.1 — —
2 199.9 Quad9 UDP 9.9.9.9 mixed A/AAAA 84 100% 9 12 9 2 0% 0% 0% — — 0% 0% 0% 0.1 — —
3 195.9 OpenDNS UDP 208.67.222.222 mixed A/AAAA 84 100% 9 13 10 2 0% 0% 0% — — 0% 0% 0% 0.1 — —
4 193.5 AdGuard UDP 94.140.14.14 mixed A/AAAA 84 100% 9 14 9 2 0% 0% 0% — — 0% 0% 0% 0.1 — —
5 188.5 Mullvad UDP 194.242.2.2 mixed A/AAAA 84 100% 10 17 10 3 0% 0% 0% — — 0% 0% 0% 0.1 — —
6 188.4 Google UDP 8.8.8.8 mixed A/AAAA 84 100% 10 16 10 3 0% 0% 0% — — 0% 0% 0% 0.1 — —
7 179.6 NextDNS UDP 45.90.30.0 mixed A/AAAA 84 100% 9 13 10 11 0% 0% 0% — — 0% 0% 0% 0.1 — —
8 139.3 Cloudflare DoH https://cloudflare-dns.com/dns-query mixed A/AAAA 84 100% 27 46 29 10 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 90%
9 138.4 Quad9 DoH https://dns.quad9.net/dns-query mixed A/AAAA 84 99% 26 43 29 12 0% 0% 0% 0% 0% 1% — — 0.1 HTTP/2 90%
10 126.7 Cloudflare (current) UDP 1.1.1.1 mixed A/AAAA 84 100% 12 47 33 93 0% 0% 0% — — 0% 0% 0% 0.1 — —
11 124.5 NextDNS DoH https://dns.nextdns.io mixed A/AAAA 84 100% 31 51 37 27 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 90%
12 116.9 Quad9-ECS DoH https://dns11.quad9.net/dns-query mixed A/AAAA 84 99% 31 79 36 22 0% 0% 0% 0% 0% 1% — — 0.1 HTTP/2 90%
13 103.8 Google DoH https://dns.google/dns-query mixed A/AAAA 84 100% 41 115 52 36 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 90%
14 088.4 AdGuard DoH https://dns.adguard.com/dns-query mixed A/AAAA 84 100% 103 205 116 41 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 90%
15 085.3 LibreDNS DoH https://doh.libredns.gr/dns-query mixed A/AAAA 84 100% 126 222 140 49 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 90%
16 076.1 Mullvad DoH https://dns.mullvad.net/dns-query mixed A/AAAA 84 100% 163 308 157 140 0% 0% 0% 0% 0% 0% — — 0.1 HTTP/2 90%
Benchmarked with dnsgauge — install via brew tap themorgantown/dnsgauge && brew install dnsgauge