AdGuard Home
Network-wide DNS server that blocks ads, trackers and malicious domains for every device that uses it, with per-client settings, a query log, statistics, encrypted DNS (DoH, DoT, DoQ, DNSCrypt) and an optional DHCP server. A single Go binary with its own web UI.
Resources by load level
What the app itself needs at each level, next to what we recommend for a server that runs only this app.
| Level | What it means | App requirements | Recommended |
|---|---|---|---|
| LightEstimate | Home network: up to 15 devices, ~20,000 DNS queries a day, the default AdGuard DNS filter (~185,000 rules), query log and statistics at their defaults. | 0.25 vCPU · 0.25 GiB RAM · 1.5 GiB disk | 0.42 vCPU · 1.8 GiB RAM · 11.04 GiB disk |
| MediumEstimate | Small office or several households: up to 50 devices, ~100,000 DNS queries a day, about 3 blocklists (~500,000 rules), DoH or DoT for some clients. | 0.5 vCPU · 0.5 GiB RAM · 7 GiB disk | 0.72 vCPU · 2.1 GiB RAM · 17.365 GiB disk |
| HeavyEstimate | Up to 250 devices or a team-wide encrypted resolver: ~500,000 DNS queries a day, ~1.1 million rules from 6–7 lists, DoH/DoT/DoQ on, query log kept 90 days. | 1 vCPU · 1 GiB RAM · 34 GiB disk | 1.32 vCPU · 2.7 GiB RAM · 48.415 GiB disk |
Recommended = app requirements + system baseline + safety headroom, under sizing policy 2026.10.0. Options stay at their defaults. “Estimate” means the sources give no number for that case, so it is worked out from them by the method stated under Components. How the numbers are built
Ready-to-run files
Support level Official install
No Compose template from ANAROQ: install it the official way.
Why: AdGuard Home is a DNS server: devices must reach it on port 53 TCP/UDP of the host (plus 67/68 UDP for DHCP, 853 for DoT/DoQ, 80/443 for its web UI and DoH, 3000 for setup). ANAROQ templates only publish ports from 1024 up, on loopback or through the proxy, so they cannot serve DNS. On most Linux servers port 53 is also held by systemd-resolved's stub listener (127.0.0.53:53), which has to be turned off first, as the official Docker guide shows.
Components
What each component needs at each load level, before baseline and headroom.
| Component | Light | Medium | Heavy | Sources |
|---|---|---|---|---|
| AdGuard Home (DNS server, web UI, optional DHCP) (app) | 0.25 / 0.25 / 1.5 | 0.5 / 0.5 / 7 | 1 / 1 / 34 | [6][9][10][17][18] |
How the estimates are worked out
- AdGuard Home (DNS server, web UI, optional DHCP) · Light: No official minimum. RAM: measured 64 MB resident (92 MB peak while loading) with the default list; 0.25 GiB leaves room for the 4 MiB DNS cache and list updates. vCPU: 20,000 queries/day is under 1 query/s on average; 0.25 is an estimate. Disk: image 29,487,891 B × 3 (0.082 GiB) + 4.4 MB list + query log 20,000 × ~400 B × 180 days (current and rotated file at the 90-day default) = 1.341 GiB, rounded up to 1.5 GiB.
- AdGuard Home (DNS server, web UI, optional DHCP) · Medium: RAM: linear between the two measurements (185,000 rules: 64 MB, peak 92 MB; 1.11 M rules: 188 MB, peak 332 MB) gives ~106 MB, ~173 MB peak at 500,000 rules; 0.5 GiB with room for TLS clients and query-log searches. vCPU: ~1.2 queries/s on average, estimate. Disk: 0.082 GiB image + ~11 MB lists + 100,000 × ~400 B × 180 days = 6.706 GiB, rounded up to 7 GiB.
- AdGuard Home (DNS server, web UI, optional DHCP) · Heavy: RAM: measured with 1,113,090 rules: 188 MB resident, 332 MB peak while lists reload, 261 MB after a burst of queries; 1 GiB is about 3× the peak. vCPU: ~6 queries/s on average with TLS handshakes for encrypted clients; 1 vCPU is an estimate. Disk: 0.082 GiB image + 25.3 MB lists + 500,000 × ~400 B × 180 days = 33.528 GiB, rounded up to 34 GiB. A shorter querylog.interval cuts this proportionally.
Ports
Public ports are meant to be reached from outside the stack, usually through a reverse proxy; internal ones stay on the stack's own network.
| Component | Port | Exposure | Purpose | Sources |
|---|---|---|---|---|
| AdGuard Home (DNS server, web UI, optional DHCP) | 53/udp | Public, through a proxy | Plain DNS on the host's interfaces; allow only your own networks | [1][2][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 53/tcp | Public, through a proxy | Plain DNS over TCP (large answers, TCP fallback); same audience as 53/udp | [1][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 67/udp | Public, through a proxy | DHCP server (off by default; LAN only, needs host networking in Docker) | [1][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 68/udp | Public, through a proxy | DHCP client side of the optional DHCP server (LAN only) | [1][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 80/tcp | Public, through a proxy | Web UI and API after setup (port chosen in the wizard; keep it off the public internet) | [1][2][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 443/tcp | Public, through a proxy | HTTPS web UI and DNS-over-HTTPS once encryption is on (collides with a host proxy) | [1][5][14] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 443/udp | Public, through a proxy | DNS-over-HTTPS over HTTP/3 once encryption is on | [1][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 853/tcp | Public, through a proxy | DNS-over-TLS once encryption is on | [1][5][14] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 853/udp | Public, through a proxy | DNS-over-QUIC once encryption is on | [1][5][14] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 3000/tcp | Internal only | First-start setup wizard on 0.0.0.0:3000, open to anyone until finished; reach via SSH tunnel | [2][5][9] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 3000/udp | Internal only | HTTP/3 on the alternative web port (exposed by the image, not needed by default) | [5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 5443/tcp | Public, through a proxy | DNSCrypt (optional) | [1][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 5443/udp | Public, through a proxy | DNSCrypt (optional) | [1][5] |
| AdGuard Home (DNS server, web UI, optional DHCP) | 6060/tcp | Internal only | pprof debug API (off by default); never publish | [1][5][9] |
User and permissions (UID/GID)
The user each container's process runs as, and the paths it writes to. A bind mount for one of these paths must be writable by that UID:GID.
| Component | UID:GID | User | Starts as root | Writes to | Sources |
|---|---|---|---|---|---|
| AdGuard Home (DNS server, web UI, optional DHCP)Derived | 0:0 | root | No | /opt/adguardhome/conf/opt/adguardhome/work | [1][5][6] |
- AdGuard Home (DNS server, web UI, optional DHCP): The image sets no USER, so AdGuard Home runs as root and never drops privileges. Its directories are owned by nobody and the binary carries the cap_net_bind_service file capability, so it can bind port 53 without root if run with another user. conf holds AdGuardHome.yaml; work/data holds the lists, statistics, sessions and query log.
Storage growth
How much each component's data grows per month at each load level, on top of the disk in the profile. A value marked Assumption is ANAROQ's stated assumption, not a figure from the sources; the notes say what it rests on.
| Component | Light | Medium | Heavy | Sources |
|---|---|---|---|---|
| AdGuard Home (DNS server, web UI, optional DHCP)Derived | 0 | 0 | 0 | [9][10][18] |
What the growth figures rest on
- AdGuard Home (DNS server, web UI, optional DHCP): The query log is capped: after 90 days (default) querylog.json is renamed to querylog.json.1, replacing the older one, so at most ~180 days stay on disk, already counted in the preset disk. Until that cap it grows ~0.224 GiB/month (queries/day × ~400 B × 30). Statistics keep 1 day by default.
- AdGuard Home (DNS server, web UI, optional DHCP): The query log is capped: after 90 days (default) querylog.json is renamed to querylog.json.1, replacing the older one, so at most ~180 days stay on disk, already counted in the preset disk. Until that cap it grows ~1.118 GiB/month (queries/day × ~400 B × 30). Statistics keep 1 day by default.
- AdGuard Home (DNS server, web UI, optional DHCP): The query log is capped: after 90 days (default) querylog.json is renamed to querylog.json.1, replacing the older one, so at most ~180 days stay on disk, already counted in the preset disk. Until that cap it grows ~5.588 GiB/month (queries/day × ~400 B × 30). Statistics keep 1 day by default.
Upgrade and rollback
How to move to a new version safely, and how to go back if it fails.
Back up first
Stop the container and copy AdGuardHome.yaml (from the conf volume) and the data directory (from the work volume), as the manual-update guide does; the running program overwrites the YAML, so do not copy or edit it while it runs. [1][3]
Upgrade steps
- Read the CHANGELOG for every version between yours and the new one: each config migration (schema_version) is listed there with its manual rollback. [8]
- In Docker the built-in updater is disabled: change the pinned adguard/adguardhome tag, docker pull it, then stop and remove the container and create it again with the same volumes and ports (or docker compose pull and up -d). [1][2]
- Check the log and the dashboard version, then send a test query (for example a blocked domain) to the server's DNS address before moving clients back. [16]DerivedThe guides give no post-upgrade check; this follows their own test of a blocked domain against the server.
Roll back
Put back the AdGuardHome.yaml from before the upgrade and run the previous tag. The new release migrates the file to a newer schema_version, and the CHANGELOG only gives manual steps to undo each migration. [3][8]
Known breaking changes
- In 0.107.78: Rule lists are capped at filtering.max_http_size (256 MB by default), and HTTP/1.1 upgrades to H2C are refused. [8][11]
- In 0.107.74: Schema 33 → 34: tls.allow_unencrypted_doh was replaced by http.doh.insecure_enabled. DoH behind a reverse proxy needs the new key; the FAQ still shows the old one. [3][8][13]
- In 0.107.34: The image's HEALTHCHECK and tini entrypoint were removed. Some Docker tools cache the old ENTRYPOINT: back up the config, remove the container, purge the old image and pull again. [8]
Limits
- Port 53 must be free on the host. On Ubuntu and most systemd distributions systemd-resolved listens on 127.0.0.53:53: put DNS=127.0.0.1 and DNSStubListener=no in /etc/systemd/resolved.conf.d/adguardhome.conf, link /etc/resolv.conf to /run/systemd/resolve/resolv.conf and restart systemd-resolved. In Docker this is not done for you. [1][3]
- On Docker's bridge network every query seems to come from the bridge gateway (such as 172.17.0.1), so per-client settings, allowed clients and the query log cannot tell devices apart. The guide uses --network host for real client IPs, and it is required for the DHCP server. [1]
- Memory grows with the total number of filtering rules (measured 64 MB with the default 185,000 rules, 188 MB with 1.1 million, with higher peaks while lists reload). The query log keeps 90 days on disk by default; set querylog.interval lower on busy servers. [9][13][17]
- Statistics need a file system that supports mmap(2); some network or special file systems do not, so keep the work volume on a local disk. [2]
Security
- Do not run an open resolver on a public server: it invites DDoS and amplification abuse. Firewall 53 to your own networks, or turn on Allowlist mode (allowed clients by ClientID or IP), or disable plain DNS and serve only DoH/DoT. Plain DNS is rate-limited to 20 queries/s per subnet by default. [4][9]
- On first start the setup wizard listens on 0.0.0.0:3000 and whoever finishes it creates the admin account. Keep 3000 closed to the internet (publish it on 127.0.0.1 and use an SSH tunnel) until setup is done. [2][9]
- Behind a reverse proxy, put the proxy's address in trusted_proxies so AdGuard Home reads the real client IP from its headers; otherwise every DoH client looks like the proxy and access settings judge the proxy, not the client. [13][14]
- The container runs as root (the image sets no USER). Keep the web UI on a private address or behind authentication at the proxy, and never publish the pprof port 6060. [1][5]
Backup
- Back up AdGuardHome.yaml (all settings, clients, custom rules and the admin password hash) and the data directory (statistics, query log, sessions, DHCP leases), with the container stopped: the running program overwrites the YAML. [1][3][13][15]
- The YAML alone restores a working server: blocklists are downloaded again from their URLs (every 24 hours by default), and only the history in the query log and statistics would be lost. [9][13]
Latest release
- This profile was checked against
AdGuard Home 0.107.79
This profile was checked against the newest release.
- Checked on
- 14 Oct 2026
- State
- Checked within the last 90 days
- Where releases are published
- GitHub Releases
Checked 2026-10-14: v0.107.79 (2026-08-18 on Docker Hub) is the newest stable tag. v0.108.0-b.91 and v1.0.0-b.1 (new UI and versioning) are betas, and v0.107.80 is only planned in the CHANGELOG.
Version
- Profile status
- Published
- Checked against release
- AdGuard Home 0.107.79
- Profile version
- 1.0.0
- Figures verified
- 14 Oct 2026
- Catalog release
- 2026.10.10
- Sizing policy
- 2026.10.0
- Compose file
- Not available yet
Project and alternatives
- Official site
- adguard.com/en/adguard-home/overview.html
- Source code
- github.com/AdguardTeam/AdGuardHome
- Alternatives
- Pi-holeTechnitium DNS Server
Sources
- AdGuard Home KB: Docker (volumes /opt/adguardhome/work and conf; ports 53, 67/68, 80, 443, 3000, 853, 5443, 6060; --network host for client IPs and DHCP; DNSStubListener=no) (Official docs · read 14 Oct 2026)
- AdGuard Home KB: Getting started (needs 3000/TCP setup, 80/TCP web UI, 53/UDP DNS; wizard on 0.0.0.0:3000; Docker auto-update disabled; setcap; mmap limitation) (Official docs · read 14 Oct 2026)
- AdGuard Home KB: FAQ (bind: address already in use = systemd-resolved on 127.0.0.53:53, fix by hand in Docker; reverse proxy; manual update backs up AdGuardHome.yaml and data/) (Official docs · read 14 Oct 2026)
- AdGuard Home KB: Running securely (public server exposed to DDoS; Allowlist mode with allowed clients; disable plain DNS; default plain-DNS ratelimit 20) (Official docs · read 14 Oct 2026)
- AdguardTeam/AdGuardHome docker/build.Dockerfile at v0.107.79 (alpine:3.23, setcap cap_net_bind_service, dirs owned by nobody, no USER, no HEALTHCHECK, EXPOSE 53…6060) (Official repository · read 14 Oct 2026)
- Docker Hub: adguard/adguardhome v0.107.79 image (linux/amd64 29,487,891 B compressed; config: no User, no Healthcheck; CMD -c conf/AdGuardHome.yaml -w work) (Official repository · read 14 Oct 2026)
- Docker Hub: adguard/adguardhome tags (v0.107.79 newest stable on 2026-08-18; v0.108.0-b.91 and v1.0.0-b.1 are betas) (Official repository · read 14 Oct 2026)
- AdguardTeam/AdGuardHome CHANGELOG.md at v0.107.79 (schema migrations with rollback steps; 0.107.74 http.doh; 0.107.78 rule-list size limit; 0.107.34 HEALTHCHECK removed) (Release notes · read 14 Oct 2026)
- AdguardTeam/AdGuardHome internal/home/config.go at v0.107.79 (defaults: web 0.0.0.0:3000, ratelimit 20, cache 4 MiB, query log 90 days, statistics 1 day, AdGuard DNS filter) (Official repository · read 14 Oct 2026)
- AdguardTeam/AdGuardHome internal/querylog/querylogfile.go at v0.107.79 (rotation renames querylog.json to querylog.json.1 once the oldest entry passes the interval) (Official repository · read 14 Oct 2026)
- AdguardTeam/AdGuardHome internal/filtering/rulelist/rulelist.go at v0.107.79 (DefaultMaxRuleListSize = 256 MB) (Official repository · read 14 Oct 2026)
- AdguardTeam/AdGuardHome README.md at v0.107.79 (based on the software behind the public AdGuard DNS servers, sharing a lot of code) (Official repository · read 14 Oct 2026)
- AdGuard Home KB: Configuration (querylog and statistics interval 1h–8760h, allowed_clients, trusted_proxies, http.doh.insecure_enabled, cache_size) (Official docs · read 14 Oct 2026)
- AdGuard Home KB: Encryption (DoH, DoT, DoQ, DNSCrypt; behind a reverse proxy set trusted_proxies to the proxy address) (Official docs · read 14 Oct 2026)
- AdGuard Home KB: DHCP (leases stored in data/leases.json) (Official docs · read 14 Oct 2026)
- AdGuard Home wiki: VPS (check the server with host doubleclick.net against it; a blocked domain answers NXDOMAIN) (Official docs · read 14 Oct 2026)
- ANAROQ measurement 2026-10-14, v0.107.79 amd64 binary from this image: RSS 64 MB (peak 92 MB) with 184,525 rules; 188 MB (peak 332 MB) with 1,113,090 rules, 25.3 MB of lists (Measurement · read 14 Oct 2026)
- ANAROQ measurement 2026-10-14, v0.107.79: 8,000 queries wrote 2,680,363 B to querylog.json (blocked entries ~325 B, answered ~375 B); stats.db 16 KiB (Measurement · read 14 Oct 2026)
- AdGuard DNS home page (hosted DNS filtering with a dashboard, by Adguard Software Ltd.) (Official docs · read 14 Oct 2026)
- AdGuard DNS KB: Private DNS overview (custom blocklists and rules, query log, statistics, parental control; between public AdGuard DNS and AdGuard Home) (Official docs · read 14 Oct 2026)