Tech Digest

Networking

Pi-hole

Network-wide DNS blocker with per-device groups and a full query log

NetworkingEUPL-1.2Maturearm64 builds
Last reviewed Profile maintained against the project's own documentation
Operational load
2 / 5
Light
Idle memory
100 MB
typical use ~220 MB
Moving parts
1
containers in a normal deployment
Backup shape
SQLite backup
needs a dump or a stop

Pi-hole is a DNS resolver that answers queries for known ad and tracker domains with nothing, for every device on the network at once. It replaces per-device browser extensions and paid filtering DNS services.

Our verdict on Pi-hole#

Pi-hole v6 (February 2025) rewrote everything you touch, and it is still what people trip over. lighttpd and PHP are gone: pihole-FTL now serves the web UI and a documented REST API itself, binding 80 and 443 and falling back to 8080 if something already owns 80. Every setting moved from setupVars.conf into /etc/pihole/pihole.toml, the CLI grew real verbs (pihole setpassword rather than pihole -a -p), and the v5 static API token is gone: you POST your password to /api/auth and receive a session ID, or you generate an application password in the UI for scripts. Docker users had the worst of it, since WEBPASSWORD became FTLCONF_webserver_api_password and DNS1/DNS2 became FTLCONF_dns_upstreams. As of September 2026 the line is FTL v6.7 / Web v6.6 / Core v6.4.3. Choose Pi-hole over AdGuard Home when you want group-based per-device rules and the deeper blocklist ecosystem.

Who Pi-hole is for#

Choose it if

  • A household where one box should filter every device including the TV and the fridge, with no client software anywhere
  • Anyone who wants to slice policy by group: kids' devices on a strict list, the work laptop on none, guests somewhere between
  • Raspberry Pi owners, since it is the reference platform and the documented 512 MB floor fits anything from a Pi 3 upward
  • People who want to replace their router's DHCP so the query log shows hostnames instead of a wall of IP addresses

Look elsewhere if

  • You want DNS-over-TLS or DNS-over-HTTPS upstreams without a second daemon; Pi-hole needs cloudflared or a similar proxy alongside it, where AdGuard Home has it built in
  • You cannot tolerate a single point of failure for name resolution and are not willing to run a second instance
  • You need per-client encrypted access from outside the LAN, which Pi-hole does not serve

What running it actually looks like#

One container, or a script install on Debian, Ubuntu, Fedora, CentOS Stream, Alpine or Raspberry Pi OS. Documented requirements are 512 MB RAM and at least 2 GB free disk, 4 GB recommended. The hard part is port 53: on Ubuntu you have to stop systemd-resolved from binding it first, and in Docker you publish 53/tcp and 53/udp plus a web port. Two volumes: /etc/pihole for config and databases, /etc/dnsmasq.d for extra dnsmasq snippets. Set FTLCONF_webserver_api_password and FTLCONF_dns_upstreams before the first boot; the old v5 variable names let the container start and then do nothing. Upgrading a v5 host in place migrates setupVars.conf into pihole.toml automatically and offers to disable lighttpd, which silently takes down anything else you were hosting on it.

Resource profile#

Memory
100 MB idle, around 220 MB in ordinary use. Documented minimum is 512 MB. FTL holds recent query data in memory, so the number tracks query volume and how many domains your blocklists total.
CPU and acceleration
Trivial in steady state. `pihole -g` (gravity rebuild) is the one spike: it downloads every list and rebuilds gravity.db, which takes tens of seconds and pegs a core on a Raspberry Pi.
Storage growth
Documented minimum 2 GB free, 4 GB recommended. pihole-FTL.db is the only file that grows, typically tens of megabytes per month for a household, trimmed by database.maxDBdays.
Operational load
2 of 5, Light. One service, two SQLite files, and updates are usually clean. It is not a 1 because it sits on the critical path for the whole network: when it is down, nothing resolves, and the v6 rewrite proved that major versions can move config and API out from under you.

Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.

Data and backup surface#

Back up /etc/pihole. pihole.toml is the entire configuration, including the web password hash and TOTP secret. gravity.db holds adlists, allow and deny entries, groups and client assignments, and is fully rebuildable with pihole -g provided you kept the list URLs. pihole-FTL.db is the long-term query log and the only file that really grows; it is trimmed by database.maxDBdays in pihole.toml and is safe to exclude entirely if you do not care about historical graphs. For a clean portable backup use the Settings then Teleporter export, which produces a single archive you can restore into a fresh install. A live cp of the SQLite files while FTL is running can catch a WAL mid-write, so stop the service or use sqlite3 ... ".backup".

Derived backup shape

SQLite backup. sqlite3 <db> ".backup out.db" while running, or stop the container and copy. A live cp of a WAL-mode SQLite file can restore corrupt.

Traps and surprises#

v6 deleted the static API token

Every v5 integration that sent ?auth=<token> broke. v6 authentication is a POST of your password to /api/auth which returns a session ID you pass as X-FTL-SID, a JSON field, a URL parameter or a cookie, and it expires. For scripts and dashboards, generate an application password in the web UI instead of embedding your real password, which is also the only way to authenticate once TOTP is enabled.

Every Docker environment variable was renamed

WEBPASSWORD is now FTLCONF_webserver_api_password, DNS1/DNS2 are now FTLCONF_dns_upstreams, WEB_PORT is FTLCONF_webserver_port, DNSSEC is FTLCONF_dns_dnssec, and ServerIP/ServerIPv6 were removed with no replacement. The container starts happily with the old names and simply ignores them, so you get a Pi-hole with a random password and default upstreams and no error anywhere. The Docker image was described as a complete rewrite for a reason.

FTL wants port 80 for itself

With lighttpd disabled, FTL's embedded web server binds 80 and 443 and only falls back to 8080 when 80 is already taken. On a machine that also runs a reverse proxy, this is a fight. On an in-place v5 upgrade the installer asks whether to disable lighttpd, and answering yes takes down any other site lighttpd was serving. Set webserver.port in pihole.toml deliberately rather than letting the fallback decide for you.

setupVars.conf is no longer read

After v6, /etc/pihole/setupVars.conf is a migration artifact. Editing it changes nothing, and plenty of older tutorials and Ansible roles still write to it. Configuration lives in /etc/pihole/pihole.toml, editable directly, via pihole-FTL --config dns.upstreams 9.9.9.9, or through the UI. In Docker there is a further twist: any setting supplied as an FTLCONF_ environment variable becomes read-only in the web interface.

Encrypted DNS in clients walks straight past you

Pi-hole only sees queries that come to it on port 53. Firefox's DNS-over-HTTPS, Chrome's secure DNS, iOS and Android private DNS profiles, and smart TVs with hardcoded resolvers all bypass it entirely, and the dashboard shows a suspiciously quiet device. Mitigations are blocking known DoH endpoint domains, blocking outbound 853 and outbound 53 to anything but the Pi-hole at the firewall, and disabling secure DNS in browser policy. There is no fix from inside Pi-hole.

Specifications#

Category
Networking, DNS and remote access
Licence
EUPL-1.2 (Copyleft)
Written in
C (pihole-FTL) and Bash (core), JavaScript web UI
First release
2015
Maturity
Mature
Datastore
SQLite (gravity.db and pihole-FTL.db) plus a TOML config file
Default ports
53, 80, 443
Ships as
docker, install script, native binary
arm64 builds
Yes
Identity
Local accounts only. A single web password with optional TOTP, plus generated application passwords for scripts. No user accounts, no OIDC, no LDAP.
Replaces
NextDNS, AdGuard DNS, Cloudflare Gateway
Project site
pi-hole.net
Source
github.com/pi-hole/pi-hole
Documentation
docs.pi-hole.net

Alternatives to Pi-hole#

Everything else in networking, dns and remote access, closest in operational weight first.

ToolOps loadIdle RAMLicence
AdGuard Home2, Light60 MBGPL-3.0
Nginx Proxy Manager2, Light100 MBMIT
wg-easy2, Light90 MBAGPL-3.0-only
Caddy1, Set and forget25 MBApache-2.0
Headscale3, Moderate40 MBBSD-3-Clause
Technitium DNS Server3, Moderate130 MBGPL-3.0

Where Pi-hole comes up elsewhere#

Sources#

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.