How To

BIND vs Dnsmasq vs PowerDNS vs Unbound [Benchmark]

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.

Original content from computingforgeeks.com - post 20125

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 CaseBest PickWhy
Authoritative + recursive (full DNS stack)BIND 9Only server that does both well in a single process
Small LAN, DHCP + DNS combo, routersDnsmasq3.8 MB RAM, reads /etc/hosts, includes DHCP and TFTP
High-traffic recursive resolverPowerDNS RecursorHighest QPS in our tests (67,712), multi-threaded
Privacy-focused recursive resolverUnboundDNS-over-TLS to upstream built in, strong DNSSEC
Authoritative with database backendPowerDNS AuthoritativeMySQL/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: dnsperf 2.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.local zone 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):

MetricBIND 9.18.39Dnsmasq 2.90PowerDNS 4.9.3Unbound 1.19.2
Queries per second47,61320,93067,71266,871
Average latency0.29 ms4.74 ms0.95 ms1.19 ms
RAM at idle38 MB3.8 MB24 MB32 MB
RAM under load45 MB5.4 MB29 MB35 MB
Query loss0.04%0%0%0%
SERVFAIL rate8.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

FeatureBIND 9DnsmasqPowerDNS RecursorUnbound
Recursive resolverYesForwarding onlyYes (full)Yes (full)
Authoritative serverYesLimitedSeparate productNo
DNSSEC validationYesYesYesYes
DNS-over-TLS (upstream)No (9.18)NoYes (4.9+)Yes
DNS-over-HTTPSNoNoYes (outgoing)Yes (with module)
DHCP serverNoYesNoNo
TFTP/PXENoYesNoNo
Database backendsNo (file zones)NoMySQL, PostgreSQL, LDAP (auth server)No
Web management UINoNoPowerDNS-AdminNo
REST APINoNoYesNo (control socket)
Split-horizon DNSYes (views)NoLua scriptingYes (access-control)
Zone transfers (AXFR/IXFR)YesNoYes (auth server)No
Response Rate LimitingYesNoNoYes (ratelimit)
Multi-threadedYesNoYesYes
Reads /etc/hostsNoYesYesNo (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.

Related Articles

Ubuntu How To Install RabbitMQ on Ubuntu 24.04 (Noble Numbat) Automation How To Install Ansible AWX on Ubuntu 22.04|20.04|18.04 Desktop How To Install Google Chrome on Ubuntu 24.04 Security Install and Configure CSF Firewall on RHEL 10 / Rocky Linux 10 / Ubuntu 24.04

Leave a Comment

Press ESC to close