Deduplicating archiver with compression and authenticated encryption for efficient, secure backups.
Table of Contents#
- Overview
- Installation
- Core Concepts
- Local Repository Setup
- Remote Repository Setup (SSH)
- Encryption and Key Management
- Compression
- Pruning and Retention
- Restoring and Verifying Backups
- Borgmatic Integration
- Systemd Timer Automation
- Troubleshooting
- See Also
- Sources
1. Overview#
Borg Backup (borgbackup) is a deduplicating backup program that stores data efficiently by identifying and keeping only unique data chunks across all archives. It supports authenticated encryption, multiple compression algorithms, and mountable backup archives. Borg operates on a repository model where each backup is stored as an archive containing a point-in-time snapshot of the source data.
Key features:
- Deduplication - content-defined chunking stores each unique block only once across all archives
- Compression - LZ4, zstd, zlib, and LZMA algorithms with configurable levels
- Encryption - AES-256-CTR with HMAC-SHA256 authentication, or AEAD (AES-OCB, CHACHA20-POLY1305)
- Mountable archives - browse backups as FUSE filesystems
- Remote repositories - native SSH transport with optional borg serve restrictions
2. Installation#
# Debian/Ubuntu
sudo apt install borgbackup
# Red Hat/Fedora
sudo dnf install borgbackup
# Arch Linux
sudo pacman -S borg
# pip (latest version)
pip install borgbackupVerify the installation:
borg --versionFor remote backups, borg must be installed on both the local and remote machines.
3. Core Concepts#
Repository - a directory (local or remote) that stores all backup data, the index, and configuration. A repository holds multiple archives.
Archive - a single backup snapshot within a repository. Each archive has a name and a timestamp. Archives share deduplicated data chunks.
Deduplication - borg splits files into variable-length chunks using a content-defined algorithm. Identical chunks (even across different files or archives) are stored only once.
Encryption modes - control how data at rest is protected. Chosen at repository init time and cannot be changed afterward.
4. Local Repository Setup#
Initializing a Local Repository#
borg init --encryption=repokey /path/to/repoCreating a Backup#
borg create --stats --progress \
/path/to/repo::{hostname}-{now:%Y-%m-%dT%H:%M} \
/home /etc /var/log \
--exclude '*.cache' \
--exclude '/home/*/.local/share/Trash'The {hostname} and {now} placeholders are expanded by borg automatically.
Listing Archives#
# List all archives in a repository
borg list /path/to/repo
# List contents of a specific archive
borg list /path/to/repo::<archive-name>Mounting an Archive#
mkdir -p /mnt/borg
borg mount /path/to/repo::<archive-name> /mnt/borg
# Browse files, then unmount:
borg umount /mnt/borg5. Remote Repository Setup (SSH)#
Borg supports remote repositories natively over SSH. The remote machine must have borg installed.
Initialize a Remote Repository#
borg init --encryption=repokey ssh://<user>@<host>:<port>/path/to/repoIf using the default SSH port (22), omit :<port>.
Create a Backup to a Remote Repository#
borg create --stats --progress \
ssh://<user>@<host>/path/to/repo::{hostname}-{now:%Y-%m-%dT%H:%M} \
/home /etcRestricting Access with borg serve#
On the remote server, restrict the SSH key in ~/.ssh/authorized_keys:
command="borg serve --restrict-to-repository /path/to/repo",restrict ssh-ed25519 AAAA... backup@clientThis limits the key to borg operations on a single repository, preventing shell access.
SSH Configuration for Convenience#
Add to ~/.ssh/config on the client:
Host borgbackup
HostName <host>
User <user>
Port <port>
IdentityFile ~/.ssh/id_borgThen use:
borg create ssh://borgbackup/path/to/repo::<archive-name> /data6. Encryption and Key Management#
Encryption Modes#
| Mode | Description |
|---|---|
repokey | Key stored in repository, passphrase protects it. Convenient for single-user. |
keyfile | Key stored in ~/.config/borg/keys/. More secure; key must be backed up separately. |
repokey-blake2 | Same as repokey but uses BLAKE2b (faster on modern CPUs). |
keyfile-blake2 | Same as keyfile but with BLAKE2b. |
authenticated | No encryption, but data integrity is verified via HMAC. |
none | No encryption, no authentication. Not recommended. |
Exporting and Backing Up Keys#
# Export the key (store this securely, off-site)
borg key export /path/to/repo /path/to/key-backup.txt
# Export as QR code for paper backup
borg key export --qr-html /path/to/repo /path/to/key-backup.htmlChanging the Passphrase#
borg key change-passphrase /path/to/repo7. Compression#
Borg supports multiple compression algorithms. Compression is specified per-archive at creation time.
Algorithm Comparison#
| Algorithm | Speed | Ratio | CPU Usage | Best For |
|---|---|---|---|---|
none | Fastest | 1:1 | Minimal | Pre-compressed data (media, archives) |
lz4 | Very fast | Low | Low | General use, fast backups |
zstd,1 to zstd,22 | Fast to slow | Medium to high | Low to high | Best balance (zstd,3 is a good default) |
zlib,1 to zlib,9 | Medium | Medium to high | Medium to high | Compatibility, moderate compression |
lzma,0 to lzma,9 | Slow | Highest | High | Archival, maximum space savings |
Usage#
# Use zstd level 3 (good default)
borg create --compression zstd,3 /path/to/repo::archive /data
# Use auto mode: compress only if it actually saves space
borg create --compression auto,zstd,6 /path/to/repo::archive /data8. Pruning and Retention#
Pruning removes old archives based on retention policies. Always run compact after pruning to reclaim disk space.
# Prune according to retention policy
borg prune --list --stats /path/to/repo \
--keep-daily=7 \
--keep-weekly=4 \
--keep-monthly=6 \
--keep-yearly=2
# Reclaim space from deleted archives
borg compact /path/to/repoThe --prefix or --glob-archives flags filter which archives the retention policy applies to:
borg prune --glob-archives '{hostname}-*' /path/to/repo --keep-daily=79. Restoring and Verifying Backups#
Full Restore#
cd /path/to/restore-target
borg extract /path/to/repo::<archive-name>Partial Restore (Specific Files or Directories)#
borg extract /path/to/repo::<archive-name> home/user/DocumentsRestore to a Different Location#
borg extract --strip-components 2 /path/to/repo::<archive-name> home/user/DocumentsVerifying Repository Integrity#
# Quick check (metadata only)
borg check /path/to/repo
# Full verification including data integrity
borg check --verify-data /path/to/repoDry-Run Extraction (Validation Without Writing)#
borg extract --dry-run --list /path/to/repo::<archive-name>10. Borgmatic Integration#
Borgmatic is a configuration-driven wrapper for borg that simplifies backup management, especially for automated setups.
Install Borgmatic#
# pip
pip install borgmatic
# Arch Linux
sudo pacman -S borgmaticGenerate Configuration#
sudo borgmatic config generateThis creates /etc/borgmatic/config.yaml. Edit it:
source_directories:
- /home
- /etc
- /var/log
repositories:
- path: ssh://<user>@<host>/path/to/repo
label: remote
exclude_patterns:
- '*.cache'
- '*/.local/share/Trash'
compression: zstd,3
retention:
keep_daily: 7
keep_weekly: 4
keep_monthly: 6
keep_yearly: 2
consistency:
checks:
- repository
- archives
hooks:
before_backup:
- echo "Starting backup at $(date)"
after_backup:
- echo "Backup completed at $(date)"
on_error:
- echo "Backup FAILED at $(date)" | mail -s "Backup failure" admin@example.comRun Borgmatic#
# Create backup, prune, and check
borgmatic
# List archives
borgmatic list
# Validate configuration
borgmatic config validate11. Systemd Timer Automation#
Systemd timers are preferred over cron for modern Linux systems due to better logging and dependency management.
Service Unit#
Create /etc/systemd/system/borgmatic.service:
[Unit]
Description=Borgmatic backup
Wants=network-online.target
After=network-online.target
ConditionACPower=true
[Service]
Type=oneshot
Nice=19
IOSchedulingClass=idle
ExecStartPre=sleep 1m
ExecStart=/usr/bin/borgmatic --verbosity -2 --syslog-verbosity 1Timer Unit#
Create /etc/systemd/system/borgmatic.timer:
[Unit]
Description=Run borgmatic backup daily
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=3h
[Install]
WantedBy=timers.targetEnable the Timer#
sudo systemctl daemon-reload
sudo systemctl enable --now borgmatic.timer
# Verify timer is scheduled
systemctl list-timers borgmatic.timer
# Check last run status
systemctl status borgmatic.service
journalctl -u borgmatic.service -eTroubleshooting#
| Issue | Cause | Solution |
|---|---|---|
Repository already exists | Re-initializing an existing repo | Use borg list to verify, do not re-init |
Failed to create/acquire lock | Another borg process is running, or stale lock | Wait for completion, or borg break-lock /path/to/repo |
Data integrity error | Corrupted chunks on disk or in transit | Run borg check --repair /path/to/repo (use with caution) |
Permission denied on remote | SSH key or borg serve restriction issue | Check authorized_keys, ensure borg is in PATH on remote |
passphrase not accepted | Wrong passphrase or corrupted key | Use exported key backup to restore; borg key import |
No space left on device | Repository disk full | Prune old archives, then borg compact to reclaim space |
| Slow backup performance | No compression or suboptimal algorithm | Use --compression zstd,3; check I/O bottlenecks with iotop |