Tuning PowerDNS with LMDB Backend for High QPS
Published:
13 Sep, 2026
Eliminating Database Latency in Authoritative DNS
Relational database backends such as MySQL (gmysql) or PostgreSQL (gpgsql) provide flexibility and clustering familiarity for PowerDNS Authoritative Server deployments. However, under synthetic loads exceeding 100,000 queries per second (QPS) per node or during sustained Layer 7 DNS amplification reflections, relational backends introduce locking contention, connection pool exhaustion, and memory copy overhead. The Lightning Memory-Mapped Database (LMDB) backend (bdig / b-lmdb) reads records directly from memory-mapped files via zero-copy transactions, eliminating SQL parsing, socket overhead, and process context switches.
Prerequisites and Kernel Preparation
Before deploying the LMDB backend, tune the Linux kernel network stack to prevent socket dropouts on the standard UDP port 53. Modify /etc/sysctl.d/99-pdns-network.conf to expand socket receive buffers and system-wide backlogs:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.netdev_max_backlog = 10000
net.ipv4.udp_rmem_min = 16384
net.ipv4.udp_wmem_min = 16384Apply the new sysctl parameters immediately using sysctl -p /etc/sysctl.d/99-pdns-network.conf.
LMDB Engine Configuration Directives
Unlike relational backends, lmdb requires fixed mapping sizes defined during allocation. If your zone data exceeds the configured lmdb-map-size, zone imports will halt with an MDB_MAP_FULL error.
Edit your primary configuration file at /etc/powerdns/pdns.conf:
# Backend Selection
launch=lmdb
lmdb-datadir=/var/lib/powerdns/lmdb
lmdb-map-size=10737418240
lmdb-sync-mode=mapasync
lmdb-shards=8
# Network and Worker Threading
receiver-threads=8
distributor-threads=8
reuseport=yes
max-packet-cache-entries=2000000
packet-cache-ttl=30
query-cache-ttl=0
cache-ttl=0
# Security and Socket Configuration
local-address=0.0.0.0, [::]
local-port=53
setuid=pdns
setgid=pdnsKey Optimization Directives Explained
| Directive | Optimal Setting | Technical Impact |
|---|---|---|
| reuseport | yes | Enables SO_REUSEPORT across kernel sockets, allowing multiple receiver threads to bind to port 53 without mutex locking in user space. |
| lmdb-sync-mode | mapasync | Flushes LMDB writes asynchronously to disk. Drastically reduces latency during DNSSEC dynamic updates and zone serial increments. |
| lmdb-shards | 8 | Splits zone data across multiple LMDB database files to eliminate multi-threaded write contention when executing zone replication. |
| query-cache-ttl | 0 | Disables internal query cache. LMDB is so fast that the mutex-locked user-space query cache often degrades multi-core throughput. |
| max-packet-cache-entries | 2000000 | Retains full wire-format DNS responses in packet memory, short-circuiting entire packet parsing pipelines for repeated requests. |
Importing Zones and Validating LMDB Performance
To populate the LMDB backend from existing BIND zone files or primary master AXFR transfers, run the dedicated pdnsutil utility:
pdnsutil load-zone example.com /var/named/zones/example.com.zone
pdnsutil secure-zone example.com
pdnsutil set-nsec3 example.com '1 0 10 abcd'Confirm the structural integrity of the newly loaded zone and check DNSSEC status with:
pdnsutil check-zone example.com
pdnsutil show-zone example.comBenchmarking and Verification
Execute synthetic stress queries against the configured node using dnsperf to observe thread utilization across all assigned vCPUs:
dnsperf -s 127.0.0.1 -p 53 -d query_dataset.txt -c 50 -l 30 -Q 150000Monitor thread performance in real-time via PowerDNS control commands:
pdns_control show packetcache-hits packetcache-misses latency-avg100 udp-queriesDeploying the LMDB backend alongside SO_REUSEPORT ensures consistent sub-millisecond query responses, linear scaling across CPU cores, and resilience against high-volume DNS traffic spikes.