BorgBackup Dedup

BorgBackup cheatsheet — init repos, create backups, prune old archives, restore files. borg create, borg prune --keep-daily 7, borg extract. Full reference.

9 min read

BorgBackup (Borg)

What it is

BorgBackup is a powerful, efficient, and secure deduplicating backup program. You reach for it when you need to back up large amounts of data, want to save disk space through deduplication, and require strong encryption.

Installation

Linux

sudo apt update && sudo apt install borgbackup
# or
sudo yum install borgbackup
# or
sudo dnf install borgbackup
# or
sudo pacman -S borgbackup

macOS

Using Homebrew:

brew install borgbackup

Windows

Borg can be run on Windows via WSL (Windows Subsystem for Linux).

  1. Install WSL: Follow Microsoft’s official guide: https://docs.microsoft.com/en-us/windows/wsl/install
  2. Install a Linux distribution: For example, Ubuntu.
  3. Install Borg within WSL:
    sudo apt update && sudo apt install borgbackup
    
    You can then access your Windows drives within WSL (e.g., /mnt/c/Users/YourUser/Documents).

Core Concepts

  • Repository: A directory where Borg stores your backup data. It’s not just a simple directory; Borg manages its internal structure for deduplication and integrity.
  • Archive: A snapshot of your data at a specific point in time. Each archive is named and contains metadata and references to data chunks.
  • Deduplication: Borg breaks files into chunks, hashes them, and only stores unique chunks. If a chunk is already in the repository, it’s simply referenced again. This saves significant space.
  • Compression: Borg can compress data chunks using various algorithms (lz4, zstd, zlib, lzma) to further reduce storage size.
  • Encryption: Borg supports authenticated encryption (AES-256-CTR or ChaCha20-Poly1305) to protect your backups. You choose between repository-specific keys or passphrase-based encryption.

Commands / Usage

Initializing a Repository

borg init --encryption=repokey /path/to/your/backup/repository
# or
borg init --encryption=keyfile /path/to/your/backup/repository
# or
borg init --encryption=passphrase /path/to/your/backup/repository

Initializes a new Borg repository. --encryption is crucial:

  • repokey: Key stored in the repository, protected by a passphrase. Recommended.
  • keyfile: Key stored in a separate file, protected by a passphrase.
  • passphrase: Key derived solely from a passphrase. No key is stored.

Creating Backups (Archives)

borg create --stats --progress \
    /path/to/your/backup/repository::my-first-backup-$(date +%Y-%m-%d_%H%M%S) \
    /home/user/documents \
    /etc

Creates a new archive named my-first-backup-YYYY-MM-DD_HHMMSS in the repository.

  • --stats: Show statistics about the backup process.
  • --progress: Show a progress bar.
  • ::archive-name: Specifies the name of the archive within the repository. Using $(date ...) is a common way to get unique, timestamped names.
  • /home/user/documents, /etc: Paths to back up.
borg create --stats --progress \
    -C zstd,10 \
    /path/to/your/backup/repository::my-compressed-backup \
    /data/large_files

Creates an archive with specific compression settings (zstd with compression level 10).

  • -C <compression_algorithm>[,<compression_level>]: Specifies compression. Options include lz4, zstd, zlib, lzma. lz4 is fast, zstd offers good balance, lzma is slow but high compression.
borg create --stats --progress \
    --exclude '/home/user/documents/cache' \
    --exclude-from '/home/user/.config/borg/exclude.list' \
    /path/to/your/backup/repository::my-backup-with-excludes \
    /home/user/documents

Creates an archive, excluding specific files or directories.

  • --exclude <pattern>: Excludes paths matching the pattern.
  • --exclude-from <file>: Reads exclusion patterns from a file.
borg create --stats --progress \
    --compression auto,lz4 \
    --chunker-params 25,10,1024 \
    /path/to/your/backup/repository::my-tuned-backup \
    /home/user/projects

Creates an archive with custom chunker parameters.

  • --compression auto,lz4: Automatically choose compression based on file type, defaulting to lz4.
  • --chunker-params <min>,<max>,<window>,<mod>[,<seed>]: Advanced tuning for how files are chunked. Defaults are usually fine.

Listing Archives

borg list /path/to/your/backup/repository

Lists all archives in the repository.

borg list --format='{archive}{N}{}/ {time}{N}{}/ {size:>10.2f} GB' \
    /path/to/your/backup/repository

Lists archives with custom formatting.

  • --format <fmt>: Use strfmt-like formatting. Common placeholders: {archive}, {time}, {size}, {comment}, {id}, {mode}, {user}, {group}.

Inspecting Archives

borg info /path/to/your/backup/repository::my-first-backup-2023-10-27_103000

Shows metadata about a specific archive.

borg mount /path/to/your/backup/repository::my-first-backup-2023-10-27_103000 /mnt/borg-restore

Mounts an archive as a FUSE filesystem, allowing you to browse it like a normal directory.

  • Requires FUSE to be installed (sudo apt install fuse or brew install fuse).
  • The mount point (/mnt/borg-restore) must exist and be empty.

Restoring Data (Extracting Archives)

borg extract --stats --progress \
    /path/to/your/backup/repository::my-first-backup-2023-10-27_103000 \
    home/user/documents/important.txt

Extracts specific files or directories from an archive to the current directory.

  • The paths specified are relative to the archive’s root.
borg extract --stats --progress \
    --to /path/to/restore/location \
    /path/to/your/backup/repository::my-first-backup-2023-10-27_103000 \
    home/user/documents

Extracts files/directories to a specified location.

  • --to <path>: Destination directory for extraction.

Pruning Old Backups (Keeping a History)

borg prune --stats --keep-daily=7 --keep-weekly=4 --keep-monthly=6 \
    /path/to/your/backup/repository

Deletes old archives based on retention rules. This is essential for managing repository size.

  • --keep-daily=N: Keep N daily archives.
  • --keep-weekly=N: Keep N weekly archives (selects one per week).
  • --keep-monthly=N: Keep N monthly archives (selects one per month).
  • --keep-yearly=N: Keep N yearly archives.
  • --prefix <name>: Apply pruning rules only to archives starting with this prefix.
  • --glob-archives <pattern>: Apply pruning rules to archives matching a glob pattern.
borg prune --stats --prefix 'my-backup-' --keep-daily=3 \
    /path/to/your/backup/repository

Prunes archives starting with my-backup-, keeping the last 3.

Compacting the Repository

borg compact /path/to/your/backup/repository

Frees up space in the repository by removing data chunks that are no longer referenced by any archive. This is often needed after pruning.

Checking Repository Integrity

borg check /path/to/your/backup/repository

Verifies the integrity of the repository data and metadata. Crucial for ensuring backups are restorable.

Repositories over SSH

Borg excels at remote backups. The repository path is specified as user@host:/path/to/repo.

# Initialize remote repository
borg init --encryption=repokey ssh://user@remote.server.com/~/borg-repo

# Create backup to remote repository
borg create --stats --progress \
    ssh://user@remote.server.com/~/borg-repo::my-remote-backup-$(date +%Y-%m-%d) \
    /home/localuser/data

# List archives on remote repository
borg list ssh://user@remote.server.com/~/borg-repo

# Restore from remote repository
borg extract --stats --progress \
    ssh://user@remote.server.com/~/borg-repo::my-remote-backup-2023-10-26 \
    home/localuser/data/config.yaml
  • Ensure you have SSH access set up (key-based auth is highly recommended).
  • Borg will prompt for the repository passphrase (and potentially SSH passphrase if not using agent forwarding or keys).

Managing Keys and Passphrases

# If using repokey or keyfile encryption, you'll be prompted for the passphrase
# when initializing, creating, or accessing the repo.

# Change passphrase for repokey/keyfile encryption
borg change-passphrase /path/to/your/backup/repository

# If using keyfile encryption, you can copy the key file
cp /path/to/repo/.config/borg/keys/key-file /path/to/safe/location

Other Useful Flags

  • --verbose, -v: Increase verbosity.
  • --debug: Show debug messages.
  • --dry-run: Perform a trial run without making changes (useful with prune).
  • --prefix <name>: Operate only on archives starting with this name.
  • --exclude-caches: Excludes directories containing a CACHEDIR.TAG file.
  • --compression-threshold <size>: Only compress files larger than this size.
  • --remote-path <path>: Specify the path to the borg binary on the remote system (if not in default PATH).
  • --append-only: Prevent modification or deletion of existing archives (useful for append-only storage).

Common Patterns

Backing up Home Directory with Retention

export BORG_REPO='ssh://user@backup.server.com/~/borg-repo'
export BORG_PASSPHRASE='your_secret_passphrase' # Use with caution, better to use env var or prompt

# Create backup
borg create --stats --progress \
    ::'{hostname}-{now:%Y-%m-%d_%H%M%S}' \
    /home/user \
    --exclude '/home/user/.cache' \
    --exclude '/home/user/Downloads' \
    --exclude-caches

# Prune old backups
borg prune --stats --keep-daily=7 --keep-weekly=4 --keep-monthly=6 \
    --prefix '{hostname}-'

This script backs up the home directory, excluding common large/temporary folders, and implements a daily/weekly/monthly retention policy. {hostname} and {now} are placeholders Borg can fill in archive names.

Restoring a Single File

borg mount /path/to/repo::my-backup-archive /mnt/borg-mount
cp /mnt/borg-mount/home/user/documents/important.txt ./
borg umount /mnt/borg-mount

A safe way to restore individual files without extracting the entire archive.

Automating Backups with Cron

Create a shell script (e.g., /usr/local/bin/borg-backup.sh) with the borg create and borg prune commands. Make it executable (chmod +x). Then add it to cron:

# Example crontab entry for daily backup at 2 AM
0 2 * * * /usr/local/bin/borg-backup.sh >> /var/log/borg-backup.log 2>&1

Security Note: Avoid hardcoding BORG_PASSPHRASE in scripts. Use borg’s passphrase prompt, or better, use BORG_PASSCOMMAND to fetch the passphrase securely (e.g., from a password manager).

Checking Repository Health Regularly

# Run daily or weekly via cron
borg check /path/to/your/backup/repository

Essential for peace of mind.

Gotchas

  • Repository Initialization: You must initialize a repository before using it. borg init is the command.
  • Encryption Choice: Choose your encryption method wisely during borg init. repokey is generally recommended. Losing the passphrase or key file means losing access to your backups.
  • Passphrase Management: Borg is very strict about passphrases. If you forget it, your data is likely gone. Store it securely. Use BORG_PASSCOMMAND for automation.
  • borg prune doesn’t free space: borg prune only removes archive metadata and unreferenced chunks. borg compact is needed to reclaim disk space.
  • SSH Authentication: For remote backups, ensure your SSH connection works flawlessly without interactive prompts (use SSH keys). Borg will prompt for the repository passphrase separately.
  • Mounting/Unmounting: Always unmount FUSE filesystems with borg umount or fusermount -u when done.
  • Exclusion Patterns: Borg uses shell-style globbing for exclusions. Be careful with path separators and wildcards. Patterns are relative to the root of the backup source unless anchored.
  • Initial Backup Size: The first backup might seem large, but subsequent backups will be significantly smaller due to deduplication, even if you back up modified files.
  • borg create vs borg diff: borg create makes a new archive. borg diff shows differences between two archives or between an archive and the current filesystem.