Skip to content
Bytearium

No ads or affiliate links active

Networking

Pi-hole or AdGuard Home? DNS ad blocking at home

A DNS ad blocker refuses to resolve known ad and tracking domains; Pi-hole and AdGuard Home both do this for a home network, with different strengths.

Your smart TV makes more phone calls than you do, and none of them are to you. A DNS blocker screens those calls for the whole house, from one small box instead of one app per device.

The short answer

Pi-hole and AdGuard Home do the same core job. They answer your devices' DNS questions and send a dead-end answer for names on a blocklist [8][11]. Both are free, and both run on a small Linux machine or in Docker. Our assessment: take Pi-hole if you like organising lists and devices in groups, take AdGuard Home if you want encrypted DNS in and out, plus parental-control features, without extra software. Neither one can block an ad that is served from the same domain as the content, such as ads inside YouTube videos [13].

How it works

  1. What a DNS blocker does. Before a device connects to a name like ads.example, it asks a resolver for the address (our article on DNS name resolution explains the chain). A blocker is a resolver with a blocklist. For a listed name it answers with nothing useful instead of the real address. Pi-hole's default is the "unspecified address", 0.0.0.0 and ::, so clients should not even try to connect [8]. Because this happens per name, it covers every app and every device that uses the blocker, smart TVs and consoles included, without installing anything on them [11].
  2. What it cannot do. AdGuard's FAQ is blunt: any ad that shares a domain with the content cannot be blocked at DNS level unless you block the content too. It names YouTube and Twitch ads and sponsored posts on Facebook, X and Instagram, and says DNS alone will never be enough for this [13]. A banner inside a page is invisible to DNS as well, because DNS only ever sees names. Treat a DNS blocker as a coarse first filter. A browser extension still catches things it cannot.
  3. The two tools in October 2026. Pi-hole v6 has an embedded web server and API inside the pihole-FTL binary, so lighttpd and PHP are gone, plus native HTTPS and a single pihole.toml file [5]. The newest Docker release, 2026.10.0 of 17 Oct 2026, bundles Core 6.5, FTL 6.8 and Web 6.6.1 [6]. The docs ask for 512 MB RAM and 2 GB free disk (4 GB recommended), list Alpine, Armbian, Debian, CentOS Stream, Fedora, Raspberry Pi OS and Ubuntu as supported systems, and want a static address, where a DHCP reservation is enough [1]. AdGuard Home's stable release is v0.107.79 from 18 Aug 2026. A beta channel (v1.0.0-b.1, 30 Sep 2026) has switched to a new interface and version scheme, so we stay on stable here [17]. Its binaries cover Linux, macOS, Windows and BSD [17]. Be careful with the vendors' own comparison tables. AdGuard's README, as retrieved on 24 Oct 2026, still says that Pi-hole needs manual lighttpd work for HTTPS [11], which predates Pi-hole v6's built-in HTTPS [5].
  4. Lists and rules. Pi-hole subscribes to blocklists and, since v6, to allowlists as well (called Antigravity) [5]. Domains, regex filters and lists can be sorted into groups [9]. AdGuard Home reads three syntaxes: Adblock-style, hosts-file style and plain domain lists. In Adblock-style, ||example.org^ blocks a domain and its subdomains, @@||example.org^ lets it through again, and /REGEX/ matches by regular expression. Adblock-style lists also work in browser blockers [15]. AdGuard also checks answers for CNAME cloaking, where an innocent-looking name secretly points to a blocked tracker [13]. Whatever you use, subscribe to a few lists, not forty. Every extra list adds names that may break something you need (our assessment).
  5. Rules per device. Pi-hole does this through groups that you assign to clients [9]. AdGuard Home has per-client configuration [11]. Both can only tell devices apart if the queries arrive from the devices themselves. Behind a router that forwards everything, all queries may look like one client (our assessment, so check the query log).
  6. Encrypted DNS. Plain DNS travels in the clear (see our DNS article). AdGuard Home supports encrypted upstreams and can serve DNS-over-HTTPS and DNS-over-TLS to your clients [11]. For Pi-hole, AdGuard's table says this needs additional software [11]. A pull request merged on 17 Jul 2026 adds native DoT and DoH upstreams to Pi-hole's FTL [10]. The FTL v6.8 release notes of 17 Oct 2026 do not list it [18], so we treat it as not yet in a stable release. Read the release notes before you rely on it.
  7. Install and ports. Pi-hole's one-step installer is curl -sSL https://install.pi-hole.net | bash. The docs also show how to read the script first, or use Docker [2]. Pi-hole answers on port 53 (TCP and UDP), serves its interface on 80 and 443, and uses 67 for the optional DHCP server [1]. AdGuard Home needs 3000/TCP for the first-run wizard, 80/TCP for the interface and 53 for DNS [12]. A service installs with sudo ./AdGuardHome -s install [12]. If something else already holds port 53, nothing starts. Ubuntu's systemd-resolved is the usual culprit, and AdGuard's FAQ lists the fix [13].
  8. Pointing devices at it. Three ways, best first. Hand out the blocker's address as DNS server in your router's DHCP settings. Or use the blocker's own DHCP server after switching DHCP off on the router. Or set it device by device as a last resort [3]. AdGuard describes the router route as well [12]. Our assessment: a second DNS server that does not filter will be used by some clients, which defeats the filter. If you add a backup, make it a second filter.
  9. Keep it inside the house. Pi-hole's firewall examples only admit your local ranges, because it was designed to work inside a local network [1]. AdGuard's hardening page tells you to bind the DNS server to a loopback or LAN interface, and to use access settings and rate limiting (default 20) if a server must be reachable from outside [16]. Updates matter. The Pi-hole 2026.10.0 release lists fixes for 17 security advisories across FTL, Web and Core [6]. AdGuard Home v0.107.79 fixed a resource-exhaustion issue in DNS-over-QUIC [17]. Pin a version, and move to the next tag on purpose after you have read its notes.
  10. What speaks against both. A blocker is a single point of failure. If it stops, every lookup fails and the network looks offline. Pi-hole's own docs warn about this for the host that uses itself as resolver [3]. False positives happen, and the one that breaks a login or a shop checkout is the one your family notices (our assessment). Devices with a hardcoded resolver, or a browser with its own encrypted DNS, skip your blocker entirely. The query log is a diary of your household, so decide how long it should keep entries. Many small sites live on ads, so allowlist the ones you want to support. If all you want is a quiet browser, an extension is less work than a server.

Side by side

Pi-holeAdGuard Home
Version checked, 24 Oct 2026Docker 2026.10.0: Core 6.5, FTL 6.8, Web 6.6.1 [6]stable v0.107.79, beta v1.0.0-b.1 [17]
Runs onlisted Linux systems or Docker [1]Linux, macOS, Windows, BSD or Docker [17]
LicenceEUPL 1.2, as named in its contribution template [10]GPL-3.0 [11]
Rule syntaxlists, regex, groups [9]Adblock-style, hosts, domains, regex [15]
Per-device rulesgroups [9]per-client settings [11]
Encrypted upstreamextra software; native support merged, not in a stable release [10][11][18]built in [11]
Serves DoH or DoTextra software [11]built in [11]
Parental control, safe searchvia extra blocklists [11]built in [11]
Optional DHCP serveryes [1]yes [11]

A homelab example

Bytearium has no DNS ad blocker on record. As of 14 to 18 Oct 2026 our inventory lists an internal DNS server as planned, not running, and we say nothing about a filter. What follows is a general walkthrough for your own Linux box, not a report from ours. Both tools are shown with a pinned image tag that exists on Docker Hub as of 24 Oct 2026 [7][14]. Pick one, because they would fight over port 53.

Pi-hole, tag 2026.10.0. The compose file follows the Pi-hole docs [4], with the web ports moved to 8080 and 8443. Put the password into a .env file as PIHOLE_PASSWORD=..., not into the compose file:

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:2026.10.0
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8080:80/tcp"
      - "8443:443/tcp"
    environment:
      TZ: "Europe/Berlin"
      FTLCONF_webserver_api_password: "${PIHOLE_PASSWORD}"
      FTLCONF_dns_listeningMode: "ALL"
    volumes:
      - "./etc-pihole:/etc/pihole"
    restart: unless-stopped

The docs say listeningMode: ALL is needed on Docker's default bridge network [4]. It also means the container accepts queries on every interface it sees, so never publish port 53 to the internet. Start it with docker compose up -d.

AdGuard Home, tag v0.107.79. The volumes and ports follow the project's Docker instructions [12][14]. Port 3000 is only for the first-run wizard:

services:
  adguardhome:
    container_name: adguardhome
    image: adguard/adguardhome:v0.107.79
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "3000:3000/tcp"
      - "8081:80/tcp"
    volumes:
      - "./work:/opt/adguardhome/work"
      - "./conf:/opt/adguardhome/conf"
    restart: unless-stopped

Open http://<server-ip>:3000, click through the wizard, and remove the 3000 line afterwards. AdGuard's docs do not auto-update Docker installs, so you change the tag yourself [12].

If Docker reports address already in use for port 53 on Ubuntu, systemd-resolved is holding it. The fix from AdGuard's FAQ is a file /etc/systemd/resolved.conf.d/adguardhome.conf with these lines [13]:

[Resolve]
DNS=127.0.0.1
DNSStubListener=no

Then point /etc/resolv.conf at the file systemd-resolved keeps without the stub, and restart the service. Skip this step and the host itself can no longer resolve names [13]:

sudo mv /etc/resolv.conf /etc/resolv.conf.backup
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
sudo systemctl reload-or-restart systemd-resolved

Test before you touch the router. On a laptop, run nslookup example.org <server-ip>, which should answer normally. Then look up a name from your blocklist; with Pi-hole's default mode the answer is 0.0.0.0 [8]. Last, change one device's DNS server, run nslookup example.org and check that the "Server" line shows the blocker, and that the request appears in the query log [13]. Only then change the router's DHCP DNS setting.

Checklist

  • Check what you want to block. If the answer is "ads in YouTube", a DNS blocker is the wrong tool.
  • Decide between the two with the table: groups and a lean footprint, or encrypted DNS and parental control built in.
  • Give the server a fixed address or a DHCP reservation before you point anything at it.
  • Pin the image tag, write down the date, and read the release notes before you change it.
  • Test with nslookup against the server's address before you change the router.
  • Keep port 53 and the admin interface off the internet.
  • Subscribe to a few lists and check the query log first when something stops working.
  • Plan for the blocker being down: know how to switch the router's DNS back in one step.
  • Check the query-log retention and delete entries you do not need.

Primary sources

These sources are the basis of this page. That does not mean every claim was checked individually; whether a review record exists is shown above under “Status”. The interpretation and checklist are our own work.

There is no documented review record for this version yet. The text relies on the sources listed.

How this page was made: Bytearium creates these pages with the help of AI and is responsible for publishing them. AI can be wrong, so we show our sources and review status openly.

  1. Pi-hole documentationPrerequisites
  2. Pi-hole documentationInstallation
  3. Pi-hole documentationPost-Install
  4. Pi-hole documentationDocker
  5. Pi-hole projectIntroducing Pi-hole v6
  6. Pi-hole projectdocker-pi-hole releases
  7. Docker Hubpihole/pihole tags
  8. Pi-hole documentationBlocking mode
  9. Pi-hole documentationGroup Management
  10. Pi-hole projectFTL pull request 2940, native DoT/DoH for encrypted upstreams
  11. AdGuardAdGuard Home README
  12. AdGuardGetting started
  13. AdGuardFAQ
  14. Docker Hubadguard/adguardhome tags
  15. AdGuardDNS filtering rules syntax
  16. AdGuardSetting up AdGuard Home securely
  17. AdGuardAdGuard Home releases
  18. Pi-hole projectFTL releases

This page has no ads and no affiliate links.