Manual backups do not scale in production. This episode introduces borgmatic: a single YAML config file that brings together source directories, repositories, retention, and checks, then runs via cron or a systemd timer. You also learn the before/after hooks and running borgmatic with verbosity and stats.

Since episode 3 we have been running Borg commands one by one manually. In the real world, nobody remembers to run borg create at 02:00 every day — and a backup that depends on human memory eventually fails. Episode 9 introduces borgmatic: a wrapper that turns your entire backup configuration into one YAML file, then schedules it with cron or a systemd timer.
Borgmatic is a Python wrapper around Borg that handles the things humans easily forget: creating archives with correct timestamp names, running prune, compact, and check in sequence, and executing hooks before and after. A single borgmatic command runs the whole pipeline. Install it from the distribution packages (sudo apt install -y borgmatic) or pipx install borgmatic for the latest version.
The borgmatic config lives at /etc/borgmatic/config.yaml (or ~/.config/borgmatic/config.yaml for a user). This file represents your entire backup policy:
source_directories:
- /home
- /etc
repositories:
- path: /backup/borg
label: local
encryption_passcommand: cat /root/.borg-passphrase
retention:
keep_daily: 7
keep_weekly: 4
keep_monthly: 6
checks:
- name: repository
frequency: 1 month
- name: data
frequency: 1 year
hooks:
before_backup:
- echo "Backup started at $(date)"
after_backup:
- echo "Backup finished at $(date)"Reading the main parts:
source_directories — the directories being backed up (equivalent to the borg create arguments).repositories — the list of repositories; borgmatic fills in BORG_REPO automatically.encryption_passcommand — the passphrase is read from a command, not hardcoded.retention — the prune rules; borgmatic maps them to borg prune.checks — the borg check schedule: repository monthly, data verification yearly.hooks — commands before and after the backup.Before running, validate first with sudo borgmatic config validate — YAML errors or unknown options surface here, not while the backup is running.
sudo borgmatic --verbosity 1 --stats--verbosity 1 shows progress per file.--stats prints a summary after the backup finishes.sudo borgmatic prune --stats, sudo borgmatic compact, or sudo borgmatic check.30 2 * * * root /usr/local/bin/borgmatic --verbosity 1 --stats >> /var/log/borgmatic.log 2>&1Cron is simple and easy to read: every day at 02:30. Logs are redirected to a file so they can be inspected (and monitored in episode 20).
Systemd gives more control: OnCalendar, RandomizedDelaySec to avoid a thundering herd, and journald integration.
[Unit]
Description=Run borgmatic backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/borgmatic --verbosity 0
[Unit]
Description=Daily schedule for borgmatic backup
[Timer]
OnCalendar=daily
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.targetEnable it with sudo systemctl daemon-reload, sudo systemctl enable --now borgmatic.timer, then check with systemctl list-timers borgmatic.timer. Persistent=true ensures the backup still runs even if the host was off when the schedule fired. RandomizedDelaySec spreads the start time randomly up to 30 minutes — helpful when many hosts start at the same hour.
Tip
A systemd timer beats cron for backups: there is a central journal, expressive OnCalendar, and Persistent=true to catch up on missed schedules. Start with cron for simplicity, move to a systemd timer when you need the control.
Hooks are borgmatic's integration points:
before_backup — runs commands before create: preparing database dumps (episode 10), checking disk space, or remounting filesystems.after_backup — cleanup and notifications.on_error — runs when the backup fails; the basis for alerting in episode 20.BORG_PASSCOMMAND is executable by the scheduler user.encryption_passcommand: without it borgmatic prompts for the passphrase interactively — which fails under cron/systemd. Mandatory for automation.config.yaml holds policy; the passphrase must not be in it. Use a passcommand that points to a 600 file or a password manager.borgmatic config validate before running.borgmatic --verbosity 1 --stats gives auditable output.Persistent=true).before_backup, after_backup, and on_error hooks are the main integration points.In episode 10 we handle the hardest backup case: consistent database backups — preparing PostgreSQL and MySQL/MariaDB dumps via hooks, ensuring WAL consistency, and the right pattern for file-based services.