Picking a DNS server for your infrastructure comes down to what you actually need it to do. A small office with 50 machines has different requirements than an ISP serving millions of queries. BIND does everything, Dnsmasq barely uses any memory, PowerDNS Recursor handles the highest query volume, and Unbound encrypts your upstream traffic by default. The “best” one depends on your use case.
We installed all four DNS servers on the same Ubuntu 24.04 VM (4 cores, 4 GB RAM), configured each as a recursive resolver with a local authoritative zone, and benchmarked them with dnsperf from a separate client on the same network. Same hardware, same OS, same queries. The numbers below come from that test, not from vendor marketing.
Current as of March 2026. Verified on Ubuntu 24.04.4 LTS with BIND 9.18.39, Dnsmasq 2.90, PowerDNS Recursor 4.9.3, Unbound 1.19.2
Quick Decision Table
If you already know what you need, start here:
| Use Case | Best Pick | Why |
|---|---|---|
| Authoritative + recursive (full DNS stack) | BIND 9 | Only server that does both well in a single process |
| Small LAN, DHCP + DNS combo, routers | Dnsmasq | 3.8 MB RAM, reads /etc/hosts, includes DHCP and TFTP |
| High-traffic recursive resolver | PowerDNS Recursor | Highest QPS in our tests (67,712), multi-threaded |
| Privacy-focused recursive resolver | Unbound | DNS-over-TLS to upstream built in, strong DNSSEC |
| Authoritative with database backend | PowerDNS Authoritative | MySQL/PostgreSQL/LDAP backends, REST API, web UI |
Test Environment
Both VMs ran on the same Proxmox VE host connected via a virtual bridge (sub-millisecond latency between them):
- DNS server VM: Ubuntu 24.04.4 LTS, 4 vCPUs (KVM), 4 GB RAM, kernel 6.8.0-101
- Client VM: Ubuntu 24.04.4 LTS, 2 vCPUs, 2 GB RAM
- Benchmark tool:
dnsperf2.14.0, 10 concurrent clients, 30-second runs, 20 unique domain queries - Each server was configured as a recursive/caching resolver with a local
lab.localzone containing 4 A records - Cache warm-up: 5-second warm-up run before each benchmark to populate the cache
Performance Comparison
These numbers were captured from cached query benchmarks (the realistic scenario for a production resolver where most queries hit cache):
| Metric | BIND 9.18.39 | Dnsmasq 2.90 | PowerDNS 4.9.3 | Unbound 1.19.2 |
|---|---|---|---|---|
| Queries per second | 47,613 | 20,930 | 67,712 | 66,871 |
| Average latency | 0.29 ms | 4.74 ms | 0.95 ms | 1.19 ms |
| RAM at idle | 38 MB | 3.8 MB | 24 MB | 32 MB |
| RAM under load | 45 MB | 5.4 MB | 29 MB | 35 MB |
| Query loss | 0.04% | 0% | 0% | 0% |
| SERVFAIL rate | 8.49% | 0% | 0% | 0% |
PowerDNS Recursor delivered the highest throughput at 67,712 QPS, with Unbound close behind at 66,871 QPS. Both are multi-threaded and scale well with CPU cores. BIND’s 8.49% SERVFAIL rate came from aggressive DNSSEC validation on certain domains during the initial cache population; once the cache warmed fully, the rate dropped. Dnsmasq is single-threaded by design, which explains the lower QPS, but it also uses 10x less memory than anything else.
BIND 9: The Full-Stack DNS Server
BIND (Berkeley Internet Name Domain) is the oldest and most widely deployed DNS server. It handles both authoritative and recursive roles in a single process, which makes it the default choice when you need one server to do everything. The ISC maintains it actively, and the 9.18.x branch is the current Extended Support Version.
Install on Ubuntu 24.04:
sudo apt install bind9 bind9-utils
BIND 9.18.39 ships in the Ubuntu 24.04 repos:
named -v
Confirmed as the Extended Support Version:
BIND 9.18.39-0ubuntu0.24.04.2-Ubuntu (Extended Support Version) <id:>
Configure recursion and an authoritative zone in /etc/bind/named.conf.options:
vi /etc/bind/named.conf.options
Set up recursive resolution for your LAN:
options {
directory "/var/cache/bind";
recursion yes;
allow-recursion { 192.168.1.0/24; localhost; };
allow-query { any; };
forwarders { };
dnssec-validation auto;
listen-on { any; };
listen-on-v6 { any; };
};
Add an authoritative zone in /etc/bind/named.conf.local:
zone "lab.local" {
type primary;
file "/etc/bind/zones/db.lab.local";
};
Create the zone file at /etc/bind/zones/db.lab.local:
$TTL 604800
@ IN SOA ns1.lab.local. admin.lab.local. (
2026032501 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns1.lab.local.
ns1 IN A 192.168.1.120
web IN A 192.168.1.10
db IN A 192.168.1.11
mail IN A 192.168.1.12
app IN A 192.168.1.13
Validate and restart:
named-checkconf
named-checkzone lab.local /etc/bind/zones/db.lab.local
systemctl restart named
The zone check confirms successful loading:
zone lab.local/IN: loaded serial 2026032501
OK
Test from the client:
dig @192.168.1.120 web.lab.local A +short
Returns the authoritative answer:
192.168.1.10
When to use BIND: you need both authoritative and recursive DNS in one server, you manage zones with DNSSEC signing, you run split-horizon DNS (different answers for internal vs external clients), or you need advanced features like TSIG zone transfers and Response Rate Limiting. For monitoring BIND in production, see our guide on monitoring BIND DNS with Prometheus and Grafana.
Dnsmasq: Lightweight DNS + DHCP for Small Networks
Dnsmasq is not trying to compete with BIND or Unbound on features. It is a lightweight DNS forwarder that also does DHCP, TFTP, and PXE boot. It reads /etc/hosts for local name resolution, caches upstream DNS responses, and uses almost no memory. You will find it running on home routers, embedded systems, and small office networks where simplicity matters more than query throughput.
Install on Ubuntu 24.04:
sudo apt install dnsmasq
Ubuntu’s systemd-resolved grabs port 53 by default. Disable it before starting Dnsmasq:
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
Configure /etc/dnsmasq.conf:
vi /etc/dnsmasq.conf
A typical caching forwarder with local records:
listen-address=0.0.0.0
bind-interfaces
server=8.8.8.8
server=1.1.1.1
cache-size=10000
# Local DNS records
address=/web.lab.local/192.168.1.10
address=/db.lab.local/192.168.1.11
address=/mail.lab.local/192.168.1.12
address=/app.lab.local/192.168.1.13
# DNSSEC validation
dnssec
trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
Restart and verify:
sudo systemctl restart dnsmasq
The entire process uses 3.8 MB of RAM at idle. That is not a typo:
ps -o rss,vsz,comm -p $(pgrep dnsmasq)
Barely a blip on any system:
RSS VSZ COMMAND
3888 16468 dnsmasq
Cached queries return in 0 ms from the client:
dig @192.168.1.120 google.com A +stats | grep "Query time"
Instant from cache:
;; Query time: 0 msec
When to use Dnsmasq: small networks (under 100 clients), home labs, development environments, anywhere you want DNS + DHCP in a single lightweight package. It is also a solid choice for DHCP in Proxmox VM environments. Not suitable for high-traffic production resolvers because of the single-threaded architecture. For a full setup walkthrough, see our Dnsmasq installation guide on Ubuntu.
PowerDNS Recursor: Highest Throughput
PowerDNS splits its DNS functions into two separate products: the Authoritative Server (for hosting zones with database backends) and the Recursor (for resolving and caching). This separation is deliberate. Each component can be optimized for its specific role without compromises.
The Recursor hit 67,712 queries per second in our benchmark, the highest of all four. It uses a multi-threaded architecture and an aggressive packet cache that serves repeated queries without touching the main cache at all.
Install on Ubuntu 24.04:
sudo apt install pdns-recursor
Version 4.9.3 ships in the Ubuntu 24.04 repos:
pdns_recursor --version 2>&1 | head -1
The version string includes feature flags showing DNSSEC, DoT, and SNMP support:
PowerDNS Recursor 4.9.3 (C) 2001-2022 PowerDNS.COM BV
Configure /etc/powerdns/recursor.conf:
vi /etc/powerdns/recursor.conf
A multi-threaded recursive resolver with DNSSEC and local hosts:
local-address=0.0.0.0
allow-from=192.168.1.0/24, 127.0.0.0/8
dnssec=validate
threads=4
max-cache-entries=10000
export-etc-hosts=on
Add local records via /etc/hosts (the Recursor reads them when export-etc-hosts=on):
echo "192.168.1.10 web.lab.local" | sudo tee -a /etc/hosts
echo "192.168.1.11 db.lab.local" | sudo tee -a /etc/hosts
Restart and check the cache stats with rec_control:
sudo systemctl restart pdns-recursor
rec_control get-all | grep -E "cache-entries|cache-hits|packetcache-hits"
After the benchmark, the packet cache handled 2.3 million hits while only 185 queries actually needed recursive resolution:
cache-entries 565
cache-hits 1
packetcache-hits 2332454
packetcache-misses 185
That packet cache is the reason PowerDNS Recursor outperforms everything else. It caches the entire DNS response packet, not just the answer records, so repeated queries skip all parsing overhead.
When to use PowerDNS Recursor: ISPs, large enterprises, or any environment where query volume justifies a dedicated recursive resolver. Pair it with the PowerDNS Authoritative Server and PowerDNS-Admin for a complete DNS infrastructure with a web management interface and database backends.
Unbound: Privacy-First Recursive Resolver
Unbound is a recursive-only resolver built with security and privacy as primary goals. It validates DNSSEC out of the box, supports DNS-over-TLS (DoT) to upstream servers, and implements query name minimization to reduce information leakage. NLnet Labs develops it, and it is the default resolver on FreeBSD and OpenBSD.
Install on Ubuntu 24.04:
sudo apt install unbound
Version 1.19.2 ships in the repos:
unbound -V 2>&1 | head -1
Confirmed:
Version 1.19.2
The key difference from the other resolvers: Unbound can forward queries to upstream servers over TLS (port 853), encrypting the traffic between your resolver and the upstream DNS provider. Configure it in /etc/unbound/unbound.conf.d/custom.conf:
vi /etc/unbound/unbound.conf.d/custom.conf
A privacy-focused resolver with DNS-over-TLS upstream and local zone:
server:
interface: 0.0.0.0
access-control: 192.168.1.0/24 allow
access-control: 127.0.0.0/8 allow
num-threads: 4
msg-cache-size: 64m
rrset-cache-size: 128m
cache-max-ttl: 86400
# DNSSEC
auto-trust-anchor-file: "/usr/share/dns/root.key"
val-clean-additional: yes
# TLS certificate bundle for upstream DoT
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
# Local zone
local-zone: "lab.local." static
local-data: "web.lab.local. IN A 192.168.1.10"
local-data: "db.lab.local. IN A 192.168.1.11"
local-data: "mail.lab.local. IN A 192.168.1.12"
local-data: "app.lab.local. IN A 192.168.1.13"
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 8.8.8.8@853#dns.google
Validate the configuration and restart:
unbound-checkconf
sudo systemctl restart unbound
Confirm no config errors:
unbound-checkconf: no errors in /etc/unbound/unbound.conf
DNSSEC validation works correctly. A domain with intentionally broken DNSSEC returns SERVFAIL (the correct behavior, it means Unbound refused to serve a potentially spoofed answer):
dig @192.168.1.120 dnssec-failed.org A | grep "status:"
Blocked as expected:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 49763
Check cache efficiency after the benchmark:
unbound-control stats_noreset | grep -E "total.num.cachehits|total.num.cachemiss|total.num.queries"
2.3 million cache hits from only 842 actual upstream lookups:
total.num.queries=2307947
total.num.cachehits=2307105
total.num.cachemiss=842
When to use Unbound: when DNS privacy matters (encrypted upstream queries), when you want strong DNSSEC validation without manual configuration, as a local resolver on individual servers, or as the recursive backend in a split DNS architecture where PowerDNS Authoritative handles the zones.
Feature Comparison
| Feature | BIND 9 | Dnsmasq | PowerDNS Recursor | Unbound |
|---|---|---|---|---|
| Recursive resolver | Yes | Forwarding only | Yes (full) | Yes (full) |
| Authoritative server | Yes | Limited | Separate product | No |
| DNSSEC validation | Yes | Yes | Yes | Yes |
| DNS-over-TLS (upstream) | No (9.18) | No | Yes (4.9+) | Yes |
| DNS-over-HTTPS | No | No | Yes (outgoing) | Yes (with module) |
| DHCP server | No | Yes | No | No |
| TFTP/PXE | No | Yes | No | No |
| Database backends | No (file zones) | No | MySQL, PostgreSQL, LDAP (auth server) | No |
| Web management UI | No | No | PowerDNS-Admin | No |
| REST API | No | No | Yes | No (control socket) |
| Split-horizon DNS | Yes (views) | No | Lua scripting | Yes (access-control) |
| Zone transfers (AXFR/IXFR) | Yes | No | Yes (auth server) | No |
| Response Rate Limiting | Yes | No | No | Yes (ratelimit) |
| Multi-threaded | Yes | No | Yes | Yes |
| Reads /etc/hosts | No | Yes | Yes | No (local-data) |
Which DNS Server Should You Choose?
BIND 9 is the Swiss Army knife. If you run your own authoritative zones with DNSSEC signing, zone transfers to secondaries, and split-horizon views, nothing else does it all in one process. The trade-off is complexity. BIND's configuration syntax has more knobs than most people will ever touch, and misconfiguration can expose your resolver to the internet.
Dnsmasq wins when simplicity and resource efficiency matter more than throughput. A Raspberry Pi running Dnsmasq can serve DNS and DHCP for an entire home network on 4 MB of RAM. It is also the fastest way to get local name resolution working: add entries to /etc/hosts and they are immediately resolvable. No zone files, no serial numbers, no reloads.
PowerDNS Recursor is the performance pick. The packet cache architecture gives it an edge in high-QPS environments. If you also need authoritative DNS with a database backend and a web UI, the PowerDNS ecosystem (Authoritative Server + Recursor + PowerDNS-Admin) gives you a modern, API-driven DNS infrastructure.
Unbound is what most people should use as a local recursive resolver. It does one thing well, validates DNSSEC without manual trust anchor management, and encrypts upstream queries with DoT. Pi-hole and AdGuard Home both use Unbound as their recommended upstream resolver for good reason.
For most home labs and small-to-medium deployments, the practical choice comes down to Dnsmasq (if you also need DHCP) or Unbound (if you want a proper validating resolver with encrypted upstream). Reserve BIND for environments that need authoritative DNS, and PowerDNS for high-traffic or database-backed setups.