Deduplicating archiver with compression and authenticated encryption for efficient, secure backups.

Table of Contents#

  1. Overview
  2. Installation
  3. Core Concepts
  4. Local Repository Setup
  5. Remote Repository Setup (SSH)
  6. Encryption and Key Management
  7. Compression
  8. Pruning and Retention
  9. Restoring and Verifying Backups
  10. Borgmatic Integration
  11. Systemd Timer Automation
  12. Troubleshooting
  13. See Also
  14. 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 borgbackup

Verify the installation:

borg --version

For 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/repo

Creating 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/borg

5. 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/repo

If 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 /etc

Restricting 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@client

This 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_borg

Then use:

borg create ssh://borgbackup/path/to/repo::<archive-name> /data

6. Encryption and Key Management#

Encryption Modes#

ModeDescription
repokeyKey stored in repository, passphrase protects it. Convenient for single-user.
keyfileKey stored in ~/.config/borg/keys/. More secure; key must be backed up separately.
repokey-blake2Same as repokey but uses BLAKE2b (faster on modern CPUs).
keyfile-blake2Same as keyfile but with BLAKE2b.
authenticatedNo encryption, but data integrity is verified via HMAC.
noneNo 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.html

Changing the Passphrase#

borg key change-passphrase /path/to/repo

7. Compression#

Borg supports multiple compression algorithms. Compression is specified per-archive at creation time.

Algorithm Comparison#

AlgorithmSpeedRatioCPU UsageBest For
noneFastest1:1MinimalPre-compressed data (media, archives)
lz4Very fastLowLowGeneral use, fast backups
zstd,1 to zstd,22Fast to slowMedium to highLow to highBest balance (zstd,3 is a good default)
zlib,1 to zlib,9MediumMedium to highMedium to highCompatibility, moderate compression
lzma,0 to lzma,9SlowHighestHighArchival, 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 /data

8. 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/repo

The --prefix or --glob-archives flags filter which archives the retention policy applies to:

borg prune --glob-archives '{hostname}-*' /path/to/repo --keep-daily=7

9. 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/Documents

Restore to a Different Location#

borg extract --strip-components 2 /path/to/repo::<archive-name> home/user/Documents

Verifying Repository Integrity#

# Quick check (metadata only)
borg check /path/to/repo

# Full verification including data integrity
borg check --verify-data /path/to/repo

Dry-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 borgmatic

Generate Configuration#

sudo borgmatic config generate

This 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.com

Run Borgmatic#

# Create backup, prune, and check
borgmatic

# List archives
borgmatic list

# Validate configuration
borgmatic config validate

11. 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 1

Timer Unit#

Create /etc/systemd/system/borgmatic.timer:

[Unit]
Description=Run borgmatic backup daily

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=3h

[Install]
WantedBy=timers.target

Enable 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 -e

Troubleshooting#

IssueCauseSolution
Repository already existsRe-initializing an existing repoUse borg list to verify, do not re-init
Failed to create/acquire lockAnother borg process is running, or stale lockWait for completion, or borg break-lock /path/to/repo
Data integrity errorCorrupted chunks on disk or in transitRun borg check --repair /path/to/repo (use with caution)
Permission denied on remoteSSH key or borg serve restriction issueCheck authorized_keys, ensure borg is in PATH on remote
passphrase not acceptedWrong passphrase or corrupted keyUse exported key backup to restore; borg key import
No space left on deviceRepository disk fullPrune old archives, then borg compact to reclaim space
Slow backup performanceNo compression or suboptimal algorithmUse --compression zstd,3; check I/O bottlenecks with iotop

See Also#

Sources#