Your Devices Are Snitches and It’s Time to Do Something About It
Open your router’s DNS query log sometime. Go ahead, I’ll wait. If you’ve never done it, prepare to feel personally betrayed by every device you own. Your smart TV — the one you bought because it had a good panel — is making thousands of DNS requests a day to analytics servers you’ve never heard of. Your phone pings ad networks in the background while it’s face-down on your desk. Your smart fridge is probably doing something unspeakable.
The fix isn’t a browser extension. Browser extensions only help one browser on one device. The fix is DNS-level blocking at the network level, which means every device — phones, TVs, game consoles, the IoT nightmare your partner calls “smart home” — gets filtered automatically, no software installation required.
Two tools dominate this space: Pi-hole, the grizzled veteran that’s been doing this since 2014, and AdGuard Home, the newer Go-powered challenger with a slicker UI and DNS-over-HTTPS baked in. Let’s figure out which one belongs on your network.
How DNS Blocking Actually Works
When your browser wants to load a page, it first asks a DNS server: “Hey, what’s the IP address for doubleclick.net?” A normal DNS server answers. A DNS ad blocker intercepts that question and responds with either a fake “nothing here” address or a flat-out refusal — the sinkhole.
The ad never loads because the DNS request never resolves. It’s elegant. The ad network never even gets a connection attempt. Your device thinks the server doesn’t exist, shrugs, and moves on.
Both Pi-hole and AdGuard Home work this way. You point your router’s DNS setting at whichever tool you’re running, and from that moment on, every device on your network is protected. No client software. No VPNs. No browser extensions. Just a DNS server with opinions.
Pi-hole: The OG DNS Sinkhole
Pi-hole has been around long enough to have a Wikipedia entry, a massive community, and enough documentation to keep you busy for a week. It was originally designed to run on a Raspberry Pi (hence the name, not the food), but it runs happily on anything: a VPS, an old laptop, a Docker container.
The tech stack: Python, PHP for the web UI, dnsmasq under the hood for actual DNS resolution, and a cron job called gravity that pulls and merges your blocklists. The Gravity blocklist system is genuinely great — you subscribe to community-maintained lists, run pihole -g to update them, and Pi-hole merges everything into a SQLite database it can query at wire speed.
What Pi-hole does well:
- Enormous community. If you have a problem, someone on Reddit solved it in 2019.
- Gravity blocklists are mature, well-maintained, and plentiful. The Firebog tick list alone covers most use cases.
- Query log and statistics dashboard are excellent. You can see exactly which device asked for what, when.
- Long-term stats are satisfying. Nothing like watching your “blocked queries” counter tick past a million and feeling like you’ve achieved something.
- Conditional forwarding lets it resolve local hostnames too, which matters if you’re running a homelab.
Where it shows its age:
- The UI is fine but feels like it was designed in 2016. Because parts of it were.
- No native DNS-over-HTTPS or DNS-over-TLS support. You need a separate tool (like cloudflared or Unbound) to encrypt your upstream DNS. Not hard, but extra steps.
- Setup on bare metal involves a curl-to-bash script, which some people are philosophically opposed to.
Pi-hole on Docker
This is the civilized way to run it:
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
ports:
- "53:53/tcp"
- "53:53/udp"
- "80:80/tcp"
environment:
TZ: 'America/New_York'
WEBPASSWORD: 'changeme'
volumes:
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
restart: unless-stopped
Port 53 is the DNS port — you need both TCP and UDP. Port 80 is the web UI. If you’re already running something on port 80 (you probably are), map it to something else like 8080:80.
One gotcha on modern Linux systems: systemd-resolved usually has port 53 bound already. You’ll need to either disable it or configure Pi-hole to use a different port and proxy through it. The Pi-hole docs cover this. It’s annoying but a one-time thing.
AdGuard Home: The Modern Challenger
AdGuard Home is a single Go binary that does everything: DNS server, DHCP server (optional), web UI, blocklist management, and encrypted DNS — all baked in. It came out of the AdGuard browser extension team and shows: the UI is polished, the defaults are sensible, and the onboarding wizard actually holds your hand through setup.
The tech stack: Go binary, built-in DNS server (no dnsmasq dependency), React frontend, and native support for DNS-over-HTTPS (DoH), DNS-over-TLS (DoT), and DNS-over-QUIC (DoQ). That last one is experimental but interesting.
What AdGuard Home does well:
- DNS-over-HTTPS and DNS-over-TLS are first-class features. Point it at 1.1.1.1 over DoH and your upstream queries are encrypted with zero extra tools.
- The UI is genuinely nicer. Filtering rules, per-client settings, and schedule-based blocking (useful if you have kids and want YouTube inaccessible after 9pm) are all right there.
- Per-client configuration is excellent. You can give your work laptop different filtering rules than the kids’ iPad. Pi-hole can do some of this but it’s more manual.
- Parental controls and safe search enforcement are built in.
- Single binary means simpler deployment and updates.
- The setup wizard is legitimately good for beginners.
Where it’s not perfect:
- Smaller community than Pi-hole. Stack Overflow is not overflowing with AdGuard Home answers.
- The blocklist ecosystem is less mature. You have fewer curated lists to choose from, though the popular ones (like those from filterlists.com) work fine.
- Query log retention and statistics aren’t quite as detailed as Pi-hole’s by default.
AdGuard Home on Docker
services:
adguardhome:
image: adguard/adguardhome:latest
container_name: adguardhome
ports:
- "53:53/tcp"
- "53:53/udp"
- "3000:3000/tcp" # setup wizard
- "80:80/tcp" # web UI after setup
- "443:443/tcp" # DoH
- "853:853/tcp" # DoT
volumes:
- './adguard/work:/opt/adguardhome/work'
- './adguard/conf:/opt/adguardhome/conf'
restart: unless-stopped
Hit port 3000 first for the setup wizard, then it moves to port 80 for the regular UI. The wizard walks you through DNS configuration, network interface selection, and admin account creation. It takes about four minutes.
Same port 53 conflict caveat as Pi-hole applies on Linux. Same fix.
Pointing Your Router at Whichever One You Chose
This is where the magic happens. The setup varies by router, but the principle is the same: log into your router admin panel, find the DHCP or DNS settings, and replace the upstream DNS server IPs with the IP address of your Pi-hole or AdGuard Home instance.
On most home routers this is under LAN Settings or DHCP Server settings. Set the “Primary DNS” to your server’s local IP (e.g., 192.168.1.100). You can leave secondary DNS blank, or point it at a public DNS as a fallback (though if your blocker is down and you fall back to 8.8.8.8, ads will slip through).
Devices pick up the new DNS via DHCP lease renewal, which happens automatically or when they reconnect. You can speed it up by renewing the lease or just rebooting things.
If you can’t change DNS on your router (some ISP-provided routers lock this down), you can configure DNS manually on individual devices, though that defeats the “every device automatically” appeal.
Blocklists: The Addiction Nobody Warns You About
Both tools support custom blocklists in various formats (hosts files, AdBlock-style rules, domain lists). And here’s the thing: once you start adding blocklists, you cannot stop.
There’s the Firebog’s Tick List for Pi-hole — a curated collection of well-maintained lists covering ads, trackers, malware domains, and telemetry. For AdGuard Home, the built-in list selector covers most bases, and you can add any URL to custom lists.
The blocklist addiction goes like this:
- You add the basic ad lists. Blocking rate: ~15%.
- You add tracker lists. Blocking rate: ~25%.
- You add telemetry lists. Your Windows PC breaks slightly. You fix it with some whitelists.
- You add malware domain lists. You feel safe.
- You find a “smart TV telemetry” specific list. Your TV stops doing anything useful. You whitelist half of it.
- You have 47 blocklists. Your blocking rate is 40%. You stare at the dashboard at 11pm on a Tuesday instead of sleeping.
This is normal. This is the path.
Whitelisting: Because You Will Break Things
Some legitimate services share domains with tracking infrastructure, and some blocklists are aggressive. Things that commonly need whitelisting:
msftconnecttest.com— Windows network check, blocking it makes Windows think you have no internetclients1.google.com— various Google services- App Store / Play Store domains if your phone starts acting up
- Smart home device cloud APIs (if you actually want them to work)
Both tools have straightforward whitelisting. In Pi-hole it’s under “Whitelist” in the UI or pihole -w domain.com from the CLI. In AdGuard Home it’s a custom filter rule: @@||domain.com^.
The query logs in both tools are invaluable here. When something breaks, check the log, filter by the affected device, and see what got blocked.
Head-to-Head Comparison
| Feature | Pi-hole | AdGuard Home |
|---|---|---|
| Setup difficulty | Medium | Easy |
| UI quality | Good | Great |
| DNS-over-HTTPS/TLS | Needs extra tool | Built-in |
| Per-client rules | Limited | Excellent |
| Blocklist ecosystem | Huge | Smaller but sufficient |
| Community/support | Very large | Smaller but growing |
| Parental controls | Basic | Good |
| Resource usage | ~50MB RAM | ~30MB RAM |
| Scheduled blocking | No | Yes |
| Docker support | Yes | Yes |
| DHCP server | Yes | Yes |
Can You Run Both? Yes, and It’s Kind of Fun
Some people run Pi-hole and AdGuard Home together, with one forwarding to the other. The most common setup: AdGuard Home handles DNS-over-HTTPS to the upstream internet, Pi-hole does blocklists and query logging, and you get the best of both.
Pi-hole → AdGuard Home (as upstream, for DoH): You keep Pi-hole’s interface and Gravity blocklists, but your upstream queries are encrypted through AdGuard Home acting as a DoH client.
AdGuard Home → Pi-hole (as upstream): AdGuard Home does the UI and per-client rules, Pi-hole does additional blocklist filtering downstream.
Is this overkill? Absolutely. Is it a perfectly reasonable way to spend a Saturday afternoon? Also absolutely. Running both adds some latency (microseconds, not anything you’d notice) and doubles the things that can break. For most people, pick one. But knowing the option exists is useful if you’re already deep in the homelab rabbit hole.
Which One Should You Actually Use?
Use Pi-hole if:
- You want the largest community and the most documentation
- You’re already comfortable with Linux administration
- You have a specific use case for the Gravity blocklist system
- You want the most detailed query statistics
Use AdGuard Home if:
- You’re newer to self-hosting and want a smoother setup experience
- You want DNS-over-HTTPS without installing extra tools
- You have kids and want per-device or scheduled filtering
- You prefer a more modern UI
- You’re running it on minimal hardware and want lower memory usage
Both are free, both run on Docker, both will meaningfully reduce the amount of tracking garbage on your network. The “correct” choice is whichever one you’ll actually set up and leave running. A Pi-hole that sits half-configured is worse than AdGuard Home that’s been running for six months.
Pick one, spend an afternoon with it, and enjoy the deeply satisfying experience of watching your router block your smart TV’s 2,000 daily attempts to tell Samsung exactly how long you stared at your screensaver. You’ve earned it.