Skip to content

Pi-hole Maintenance and Advanced Configuration

After the Pi is set up and running, use this page as a reference for running manual updates, configuring backups of your Pi configuration, or to use a USB drive to store logs.

All of these sections are optional.

Update the Pi-hole software and refresh the Gravity database with updated lists.

Run these whenever Pi-hole releases a new version, or after adding or changing blocklists.

From the Pi
sudo pihole -up
pihole -g

Pi-hole’s Teleporter exports your full configuration: blocklists, allowlists, custom domains, regex rules, DNS settings, and DHCP config.

  1. In the Pi-hole web interface, go to Settings > Teleporter.
  2. Select Export to download a backup file.

To restore after a rebuild or SD card failure, use the Import option on the same page and select the backup file.

Re-export after making significant changes to lists or settings. Store the backup file somewhere other than the Pi, such as on your local computer, a NAS, or cloud storage.

Advanced Pi-hole Configuration with pihole.toml

Section titled “Advanced Pi-hole Configuration with pihole.toml”

If you need to configure Pi-hole’s DNS behavior outside the web interface, edit /etc/pihole/pihole.toml directly.

After editing, restart the FTL service to apply changes:

From the Pi
sudo systemctl restart pihole-FTL

pihole-FTL is the core Pi-hole system service. It needs to be restarted when you make core configuration changes.

In the [dns] section of pihole.toml:

pihole.toml
[dns]
upstreams = ["127.0.0.1#5335", "1.1.1.1"] # unbound on localhost, Cloudflare backup

Or for Cloudflare directly:

pihole.toml
[dns]
upstreams = ["1.1.1.1", "1.0.0.1"]

This is the full pihole.toml from my setup, with comments stripped and the password hash redacted. Values marked ### CHANGED were modified from the Pi-hole default.

pihole.toml (v6.5, comments stripped)
# Pi-hole configuration file (v6.5)
# Reference config - comments stripped, default values preserved for reference.
# Values marked ### CHANGED were modified from the Pi-hole default.
# To apply: copy to /etc/pihole/pihole.toml, then sudo systemctl restart pihole-FTL
[dns]
upstreams = [
"127.0.0.1#5335",
"1.1.1.1"
] ### CHANGED, default = []
CNAMEdeepInspect = true
blockESNI = true
EDNS0ECS = true
ignoreLocalhost = false
showDNSSEC = true
analyzeOnlyAandAAAA = false
piholePTR = "PI.HOLE"
replyWhenBusy = "ALLOW"
blockTTL = 2
hosts = []
domainNeeded = false
expandHosts = false
bogusPriv = true
dnssec = false
interface = "eth0" ### CHANGED, default = ""
hostRecord = ""
listeningMode = "LOCAL"
queryLogging = true
cnameRecords = []
port = 53
localise = true
revServers = []
[dns.domain]
name = "lan"
local = true
[dns.cache]
size = 10000
optimizer = 3600
upstreamBlockedTTL = 86400
rrtype = "ANY"
[dns.blocking]
active = true
mode = "NULL"
edns = "TEXT"
[dns.specialDomains]
mozillaCanary = true
iCloudPrivateRelay = true
designatedResolver = true
[dns.reply.host]
force4 = false
IPv4 = ""
force6 = false
IPv6 = ""
[dns.reply.blocking]
force4 = false
IPv4 = ""
force6 = false
IPv6 = ""
[dns.rateLimit]
count = 1000
interval = 60
[dhcp]
active = false
start = ""
end = ""
router = ""
netmask = ""
leaseTime = ""
ipv6 = false
rapidCommit = false
multiDNS = false
logging = false
ignoreUnknownClients = false
hosts = []
[ntp]
[ntp.ipv4]
active = true
address = ""
[ntp.ipv6]
active = true
address = ""
[ntp.sync]
active = true
server = "pool.ntp.org"
interval = 3600
count = 8
[ntp.sync.rtc]
set = false
device = ""
utc = true
[resolver]
resolveIPv4 = true
resolveIPv6 = true
networkNames = true
refreshNames = "IPV4_ONLY"
[database]
DBimport = true
maxDBdays = 91
DBinterval = 60
useWAL = true
forceDisk = false
[database.network]
parseARPcache = true
expire = 91
[webserver]
domain = "pi.hole"
acl = ""
port = "80o,443os,[::]:80o,[::]:443os"
threads = 50
headers = [
"X-DNS-Prefetch-Control: off",
"Content-Security-Policy: default-src 'none'; connect-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; manifest-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'",
"X-Frame-Options: DENY",
"X-XSS-Protection: 0",
"X-Content-Type-Options: nosniff",
"Referrer-Policy: strict-origin-when-cross-origin"
]
serve_all = false
advancedOpts = []
[webserver.session]
timeout = 1800
restore = true
[webserver.tls]
cert = "/etc/pihole/tls.pem"
validity = 47
[webserver.paths]
webroot = "/var/www/html"
webhome = "/admin/"
prefix = ""
[webserver.interface]
boxed = true
theme = "default-auto"
[webserver.api]
max_sessions = 16
prettyJSON = false
pwhash = "" ### CHANGED from default (use `sudo pihole setpassword` to set)
totp_secret = ""
app_pwhash = ""
app_sudo = false
cli_pw = true
excludeClients = []
excludeDomains = []
maxHistory = 86400
maxClients = 10
client_history_global_max = true
allow_destructive = true
[webserver.api.temp]
limit = 60.000000
unit = "C"
[files]
pid = "/run/pihole-FTL.pid"
database = "/etc/pihole/pihole-FTL.db"
tmp_db = "/etc/pihole/pihole-tmp.db"
gravity = "/etc/pihole/gravity.db"
gravity_tmp = "/tmp"
macvendor = "/etc/pihole/macvendor.db"
pcap = ""
[files.log]
ftl = "/var/log/pihole/FTL.log"
dnsmasq = "/var/log/pihole/pihole.log"
webserver = "/var/log/pihole/webserver.log"
[misc]
privacylevel = 0
delay_startup = 0
nice = -10
addr2line = true
etc_dnsmasq_d = false
dnsmasq_lines = []
extraLogging = false
readOnly = false
normalizeCPU = true
hide_dnsmasq_warn = false
hide_connection_error = false
[misc.check]
load = true
shmem = 90
disk = 90
[debug]
database = false
networking = false
locks = false
queries = false
flags = false
shmem = false
gc = false
arp = false
regex = false
api = false
tls = false
overtime = false
status = false
caps = false
dnssec = false
vectors = false
resolver = false
edns0 = false
clients = false
aliasclients = false
events = false
helper = false
config = false
inotify = false
webserver = false
extra = false
reserved = false
ntp = false
netlink = false
timing = false
all = false

The Pi-hole FTL database (pihole-FTL.db) grows continuously and can wear out an SD card over months. Move the database and log file to a USB drive to protect the SD card and extend its life.

  • A USB flash drive
  • The Pi running with Pi-hole installed
  1. Plug in the USB drive and find its device name:

    From the Pi
    lsblk

    Look for a /dev/ that wasn’t there before, such as /dev/sda with a partition at /dev/sda1.

  2. Get the partition’s UUID:

    From the Pi
    sudo blkid /dev/sda1

    Copy the UUID value from the output.

  3. Create a mount point:

    From the Pi
    sudo mkdir -p /mnt/pihole-logs
  4. Add an entry to /etc/fstab to auto-mount on boot. Open the file and add this line at the bottom, replacing YOUR-UUID with the UUID you copied:

    /etc/fstab
    UUID=YOUR-UUID /mnt/pihole-logs ext4 defaults,noatime 0 2

    Note that this example uses ext4. If your USB drive is formatted as exFAT or NTFS instead of ext4, change the filesystem type accordingly.

    If you need to format the drive first

    This will delete everything on the drive:

    From the Pi
    sudo mkfs.ext4 /dev/sda1
  5. Mount everything in fstab:

    From the Pi
    sudo mount -a

    If this returns an error, double-check the UUID and filesystem type in /etc/fstab.

  6. Set ownership so Pi-hole’s FTL process can write to the drive:

    From the Pi
    sudo chown pihole:pihole /mnt/pihole-logs
  1. Back up the current pihole.toml:

    From the Pi
    sudo cp /etc/pihole/pihole.toml /etc/pihole/pihole.toml.bak
  2. Move the existing database to the USB drive (so you don’t lose query history):

    From the Pi
    sudo systemctl stop pihole-FTL
    sudo mv /etc/pihole/pihole-FTL.db /mnt/pihole-logs/
    sudo mv /var/log/pihole/pihole.log /mnt/pihole-logs/ 2>/dev/null || true
  3. Edit /etc/pihole/pihole.toml to update the file paths. Find the [files] section and set:

    pihole.toml
    [files]
    database = "/mnt/pihole-logs/pihole-FTL.db"
    log = "/mnt/pihole-logs/pihole.log"

    If there is no [files] section, add it at the end of the file.

  4. Start FTL and verify it comes up cleanly:

    Terminal window
    sudo systemctl start pihole-FTL
    sudo systemctl status pihole-FTL
  5. Confirm the database is on the USB drive and growing:

    From the Pi
    ls -lh /mnt/pihole-logs/
  6. Reboot the Pi:

    From the Pi
    sudo reboot now
  7. Verify that the USB drive mounts and Pi-hole starts correctly:

    From the Pi
    lsblk
    systemctl status pihole-FTL

    The FTL service won’t start if it can’t find the database file. DNS queries from all network devices will fail until the mount is fixed.

By default, Pi-hole keeps 91 days of query history.

If you want to change the database size:

  1. Set a the number of days to keep the database in pihole.toml:

    pihole.toml
    [database]
    maxDBdays = 180
  2. Restart FTL after changing this:

    From the Pi
    sudo systemctl restart pihole-FTL