Run Your Own DNS: Pi-hole vs AdGuard Home for Your Home Lab
Your ISP's DNS servers are slow, unreliable, and log everything you do. Google's 8.8.8.8 is fast but feeds your browsing data into the advertising machine. Cloudflare's 1.1.1.1 is better on privacy, but you're still trusting a third party with every domain lookup your household makes.
Running your own DNS server gives you three things: network-wide ad blocking (every device, no browser extensions), local DNS records (access services by name instead of IP), and control over your DNS data. It's one of the most impactful upgrades you can make to a home lab, and it takes about 15 minutes to set up.
The two leading options are Pi-hole and AdGuard Home. Both block ads at the DNS level, both provide local DNS, and both have active communities. They approach the problem differently enough that the choice matters. This guide covers setting up both, then compares them head-to-head so you can pick the right one.
How DNS-Level Ad Blocking Works
When you visit a website, your browser asks a DNS server to resolve the domain name to an IP address. Before loading example.com, it also tries to load ads.tracking-company.com, pixel.facebook.net, analytics.google.com, and dozens of other tracking and advertising domains.
A DNS-based ad blocker intercepts these lookups. When a request comes in for a domain on a blocklist, it returns 0.0.0.0 (or NXDOMAIN) instead of the real IP. The ad never loads. The tracker never fires. This happens at the network level, so it works for every device — phones, smart TVs, IoT gadgets, gaming consoles — without installing anything on the device.
Limitations worth knowing upfront:
- Can't block ads served from the same domain as content (e.g., YouTube ads come from
youtube.com) - Can't block in-app ads that don't use DNS (some apps hardcode IP addresses)
- Breaks some services if you block too aggressively (you'll need to whitelist)
- Doesn't replace a browser ad blocker like uBlock Origin for fine-grained control
Think of DNS blocking as the first layer of defense. It catches 70-80% of ads and trackers with zero per-device configuration. Browser extensions handle the rest.
Setting Up Pi-hole
Pi-hole is the original network-wide ad blocker. First released in 2015, it's mature, well-documented, and has a massive community. It runs on Linux natively or in Docker.
Docker Installation (Recommended)
# docker-compose.yml
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "8080:80/tcp"
environment:
TZ: "America/New_York"
WEBPASSWORD: "your-secure-password"
FTLCONF_dns_listeningMode: "all"
FTLCONF_dns_upstreams: "1.1.1.1;1.0.0.1"
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d
docker compose up -d
Access the admin panel at http://YOUR_SERVER_IP:8080/admin.
Bare Metal Installation
If you prefer running Pi-hole directly on a Raspberry Pi or Linux server:
curl -sSL https://install.pi-hole.net | bash
The installer walks you through selecting an upstream DNS provider, blocklists, and web interface options. It takes about 5 minutes.
Configuring Pi-hole
Upstream DNS. Pi-hole forwards queries it can't answer to an upstream resolver. Go to Settings > DNS and pick your upstream:
| Provider | Primary | Secondary | Privacy |
|---|---|---|---|
| Cloudflare | 1.1.1.1 | 1.0.0.1 | Good (privacy-focused) |
| Quad9 | 9.9.9.9 | 149.112.112.112 | Good (malware blocking) |
| 8.8.8.8 | 8.8.4.4 | Logs queries | |
| NextDNS | Custom | Custom | Good (configurable) |
For maximum privacy, run Unbound alongside Pi-hole as a recursive resolver that queries root servers directly, eliminating the upstream dependency entirely.
Blocklists. Pi-hole ships with a default blocklist (Steven Black's unified hosts). Add more under Adlists:
# Popular blocklists to add
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/pro-onlydomains.txt
https://big.oisd.nl/domainswild
https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20Anti-Malware%20List/AntiMalwareHosts.txt
After adding lists, go to Tools > Update Gravity to pull and compile them. A well-curated setup blocks 200,000-500,000 domains.
Be careful with aggressive lists. More blocked domains means more potential breakage. Start with the defaults plus one or two curated lists, use the system for a week, and add more as needed.
Setting Up AdGuard Home
AdGuard Home is the newer contender, first released in 2018 by AdGuard Software. It's a complete DNS server with filtering built in, not a layer on top of dnsmasq like Pi-hole.
Docker Installation
# docker-compose.yml
services:
adguardhome:
image: adguard/adguardhome:latest
container_name: adguardhome
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "3000:3000/tcp" # Initial setup UI
- "8080:80/tcp" # Admin UI after setup
volumes:
- ./work:/opt/adguardhome/work
- ./conf:/opt/adguardhome/conf
docker compose up -d
Open http://YOUR_SERVER_IP:3000 for the initial setup wizard. After setup, the admin UI moves to port 80 (mapped to 8080 above).
Bare Metal Installation
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v
Or download the binary directly from the GitHub releases and run it:
./AdGuardHome -s install
Configuring AdGuard Home
Upstream DNS. Under Settings > DNS settings, configure upstream servers:
# Standard
1.1.1.1
1.0.0.1
# DNS-over-HTTPS (encrypted)
https://dns.cloudflare.com/dns-query
https://dns.quad9.net/dns-query
# DNS-over-TLS (encrypted)
tls://1dot1dot1dot1.cloudflare-dns.com
tls://dns.quad9.net
AdGuard Home natively supports DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT) for upstream queries. Pi-hole requires additional setup (cloudflared or stubby) for encrypted upstream. This is a genuine advantage for AdGuard Home.
Blocklists. Under Filters > DNS blocklists, add lists:
AdGuard Home ships with its own default list. You can add the same third-party lists used with Pi-hole:
https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/pro.txt
https://big.oisd.nl
https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
AdGuard Home supports both hosts-format and adblock-format filter lists, giving it access to a wider range of lists than Pi-hole (which only supports hosts format natively).
Local DNS Records
Both tools let you create local DNS records so you can access home lab services by name.
Pi-hole Local DNS
Go to Local DNS > DNS Records:
| Domain | IP |
|---|---|
| proxmox.home.lab | 192.168.1.10 |
| nas.home.lab | 192.168.1.20 |
| grafana.home.lab | 192.168.1.50 |
| jellyfin.home.lab | 192.168.1.50 |
You can also create CNAME records under Local DNS > CNAME Records.
For more advanced configurations, create custom dnsmasq files:
# /etc/dnsmasq.d/05-custom.conf (or mount into Docker)
address=/home.lab/192.168.1.50
This acts as a wildcard: anything ending in .home.lab resolves to 192.168.1.50. Combined with a reverse proxy, this means you never need to add individual DNS records for new services.
AdGuard Home Local DNS
Go to Filters > DNS rewrites:
- Domain:
grafana.home.lab - Answer:
192.168.1.50
AdGuard Home also supports wildcard rewrites:
- Domain:
*.home.lab - Answer:
192.168.1.50
This is configured directly in the UI without touching config files. A small but nice usability win for AdGuard Home.
Conditional Forwarding
Conditional forwarding lets your DNS server resolve local hostnames by forwarding requests for your local domain to your router's DNS.
For example, if your router assigns hostnames like laptop.localdomain, you can configure conditional forwarding so Pi-hole or AdGuard Home asks the router to resolve those names.
Pi-hole Conditional Forwarding
Go to Settings > DNS > Conditional Forwarding:
- Enable conditional forwarding
- Local network in CIDR notation:
192.168.1.0/24 - IP address of your DHCP server (router):
192.168.1.1 - Local domain name:
localdomain(or whatever your router uses)
AdGuard Home Conditional Forwarding
In Settings > DNS settings, under Upstream DNS servers, add a rule using the bracket syntax:
[/localdomain/]192.168.1.1
[/168.192.in-addr.arpa/]192.168.1.1
The first line forwards forward lookups for .localdomain to your router. The second line handles reverse DNS for the 192.168.x.x range.
DHCP Integration
Both tools can act as a DHCP server, replacing your router's DHCP. This gives you tighter integration between DNS and DHCP — the DNS server automatically knows the hostname of every device that gets an IP via DHCP.
Should You Use Pi-hole or AdGuard Home for DHCP?
Pros:
- Automatic DNS registration for all DHCP clients
- Better device identification in the DNS query log
- Static DHCP leases managed in one place
Cons:
- If Pi-hole/AdGuard goes down, new devices can't get IP addresses
- More critical than DNS alone (DNS failure = slow browsing, DHCP failure = no network for new connections)
- Your router's DHCP might offer features like VLAN-aware assignment that Pi-hole/AdGuard don't support
The safe approach: keep DHCP on your router and use conditional forwarding for hostname resolution. Move DHCP to Pi-hole/AdGuard only if you specifically need tighter integration and have a reliable server setup (ideally with a secondary DNS running on different hardware).
Pi-hole DHCP Setup
Go to Settings > DHCP:
- Disable DHCP on your router first
- Enable DHCP in Pi-hole
- Set the IP range (e.g., 192.168.1.100 - 192.168.1.250)
- Set the gateway (your router's IP)
AdGuard Home DHCP Setup
Go to Settings > DHCP settings:
- Disable DHCP on your router first
- Select the correct network interface
- Set the gateway IP, subnet mask, and IP range
- Enable the DHCP server
AdGuard Home's DHCP implementation also supports DHCPv6 out of the box.
Pi-hole vs AdGuard Home: Head-to-Head
| Feature | Pi-hole | AdGuard Home |
|---|---|---|
| First release | 2015 | 2018 |
| Architecture | dnsmasq + FTL + web UI | Single Go binary |
| RAM usage | ~80-120 MB | ~50-80 MB |
| Encrypted upstream DNS | Requires cloudflared/stubby | Built-in (DoH, DoT, DoQ) |
| Encrypted client DNS | Requires separate setup | Built-in DoH/DoT server |
| Filter list format | Hosts format only | Hosts + Adblock syntax |
| Wildcard DNS rewrites | Via dnsmasq config | Built-in UI option |
| Query log detail | Excellent (FTL database) | Good |
| Statistics/dashboard | Very detailed | Clean and functional |
| Per-client settings | Limited (groups) | Yes (per-client filtering) |
| DHCP server | Yes (IPv4) | Yes (IPv4 + IPv6) |
| Community | Massive (Reddit, forums) | Growing |
| API | Yes | Yes |
| Mobile app | Third-party apps | Third-party apps |
Where Pi-hole Wins
Mature ecosystem. Pi-hole has been around longer, has more community resources, more troubleshooting guides, and more third-party integrations. If you Google a Pi-hole problem, someone has already solved it.
Query log and statistics. Pi-hole's FTL (Faster Than Light) engine stores query data in an efficient database with rich filtering. The long-term statistics dashboard is more detailed and configurable than AdGuard Home's.
Community blocklists. The blocklist ecosystem was built around Pi-hole. While AdGuard Home supports the same lists, Pi-hole's gravity system for managing and updating lists is mature and well-understood.
Where AdGuard Home Wins
Encrypted DNS everywhere. DoH and DoT support — both as a client (upstream) and as a server (for your devices) — is built in and works without extra software. This is AdGuard Home's biggest technical advantage.
Per-client filtering. You can set different blocklists for different devices. The kids' tablets get aggressive filtering. Your workstation gets a lighter touch. Pi-hole's group management offers something similar but it's less intuitive.
Adblock syntax support. AdGuard Home understands adblock-format filter rules, which are more expressive than hosts-format rules. This gives access to more granular filtering lists that Pi-hole can't use natively.
Simpler deployment. Single binary, single config file, cleaner architecture. Less can go wrong during installation and upgrades.
Wildcard DNS in the UI. Creating *.home.lab rewrites without touching config files is a small thing, but it's representative of AdGuard Home's more polished configuration experience.
The Recommendation
Choose Pi-hole if you value the mature community, want the most detailed query logs, or are following guides and tutorials (most assume Pi-hole).
Choose AdGuard Home if you want encrypted DNS without extra complexity, per-client filtering, a cleaner architecture, or you're starting fresh with no existing preference.
If you held a gun to my head: AdGuard Home is the better product in 2026. Its technical advantages (encrypted DNS, adblock syntax, per-client rules) are meaningful, and its gap in community resources has narrowed substantially. But Pi-hole is still excellent and you won't be disappointed with either.
Pointing Your Network at Your DNS Server
After setup, you need your devices to actually use it.
Option 1: Router-Level Configuration (Best)
Log into your router and change the DNS server settings:
- Primary DNS: Your Pi-hole/AdGuard Home IP (e.g., 192.168.1.50)
- Secondary DNS: Leave blank, or set a fallback (see note below)
Every device that uses DHCP will get the new DNS settings on their next lease renewal. Force it immediately:
# On Linux
sudo dhclient -r && sudo dhclient
# On Windows
ipconfig /release && ipconfig /renew
# On macOS
sudo ipconfig set en0 DHCP
A note on secondary DNS: If you set a secondary DNS (like 1.1.1.1), devices will sometimes use it directly, bypassing your ad blocker. For consistent blocking, either don't set a secondary DNS, or run a second Pi-hole/AdGuard Home instance on different hardware.
Option 2: Per-Device Configuration
On individual devices, set the DNS server manually:
# Linux (systemd-resolved)
sudo nano /etc/systemd/resolved.conf
# Set: DNS=192.168.1.50
sudo systemctl restart systemd-resolved
# Or with nmcli
nmcli con mod "Your Connection" ipv4.dns "192.168.1.50"
nmcli con up "Your Connection"
Option 3: DHCP-Level Configuration
If your router supports setting DNS servers in DHCP options (most do), configure DHCP to hand out your Pi-hole/AdGuard Home IP as the DNS server. This is functionally the same as Option 1 but done at the DHCP level rather than the router's own DNS forwarding.
Troubleshooting
Devices bypassing your DNS
Some devices (Google Chromecast, Roku, certain IoT devices) hardcode DNS servers like 8.8.8.8. They'll bypass your Pi-hole/AdGuard Home entirely.
Fix this with a firewall rule that redirects all DNS traffic to your server:
# iptables — redirect all DNS to Pi-hole
sudo iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to 192.168.1.50:53
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 53 -j DNAT --to 192.168.1.50:53
If you're running pfSense or OPNsense, this is a NAT port forward rule.
Slow DNS resolution after setup
If everything feels slow after switching DNS, check:
- Is the DNS server responding?
dig @192.168.1.50 google.com - Is the upstream resolver accessible from the server?
- Is the query log showing timeouts?
- Restart the service and try again
Websites or apps breaking
Check the query log for blocked domains when the issue occurs. Whitelist the domain causing the problem:
Pi-hole: Go to Query Log, find the blocked domain, click Whitelist.
AdGuard Home: Go to Query Log, find the blocked domain, click Unblock.
Common domains you might need to whitelist:
s.youtube.com(YouTube history)cdn.optimizely.com(some sites break without it)clients4.google.com(Chromecast)msftconnecttest.com(Windows connectivity check)
Port 53 already in use
On Ubuntu/Fedora, systemd-resolved often occupies port 53. Disable its stub listener:
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
Or, if running in Docker, use a different host port and configure your router to use that port (though port 53 is standard and some devices won't work with non-standard DNS ports).
Running Both for Redundancy
For a production home lab, consider running two DNS servers on separate hardware. If one goes down, DNS still works.
Run Pi-hole on one machine and AdGuard Home on another (or two instances of the same software). Configure your router to hand out both IPs as DNS servers. Keep the blocklists synchronized manually, or use a tool like Gravity Sync (for Pi-hole pairs) to keep them in sync.
This isn't overkill. DNS is the most critical service in your network. When DNS is down, everything appears to be down. A second instance on a $35 Raspberry Pi is cheap insurance.