BorgBackup — Deduplicating, Encrypted Backups
Practical guide to BorgBackup: deduplicated, compressed and encrypted backups that store only changed data chunks — ideal for large, frequently changing datasets.
BorgBackup (the binary is borg) is a deduplicating backup tool: it splits your data into chunks and stores each block exactly once — no matter how many archives or backup runs it appears in. That saves a striking amount of space, and combined with compression and authenticated encryption you get backups that sit comfortably even on untrusted storage or on a remote server over SSH. This guide takes you from initializing a repository through creating and restoring archives to retention policies and automation.
Repository Initialization
borg init --encryption=repokey <path> — Initialize a new local repository with encryption. The key is stored in the repository itself.
borg init --encryption=repokey /mnt/backup/myrepoborg init --encryption=keyfile <path> — Initialize a repository with encryption. The key is stored in ~/.config/borg/keys (safer for offsite repos).
borg init --encryption=keyfile /mnt/backup/myrepoborg init --encryption=none <path> — Initialize a repository without encryption. Not recommended for sensitive data.
borg init --encryption=none /tmp/testrepoborg init --encryption=repokey-blake2 <path> — Initialize with repokey encryption using BLAKE2b (faster than SHA-256 on modern hardware).
borg init --encryption=repokey-blake2 /mnt/backup/myrepoborg init --encryption=repokey <user>@<host>:<path> — Initialize a repository on a remote server via SSH.
borg init --encryption=repokey user@server.com:/backup/repoCreating Archives
borg create <repo>::<archive> <path> — Create a new archive in the repository. Archive names must be unique.
borg create /mnt/backup/repo::home-2024-01-15 /home/userborg create <repo>::'{hostname}-{now:%Y-%m-%d}' <path> — Create an archive with an automatic name using placeholders for hostname and date.
borg create /mnt/backup/repo::'{hostname}-{now:%Y-%m-%d}' /home/userborg create --stats <repo>::<archive> <path> — Show backup statistics (original size, compressed size, deduplicated size) after completion.
borg create --stats /mnt/backup/repo::backup-today /homeborg create --progress <repo>::<archive> <path> — Show progress during backup creation.
borg create --progress /mnt/backup/repo::daily-backup /homeborg create --exclude <pattern> <repo>::<archive> <path> — Exclude files matching a pattern from the archive.
borg create --exclude '/home/*/.cache' /mnt/backup/repo::home-backup /homeborg create --exclude-from <file> <repo>::<archive> <path> — Read exclude patterns from a file.
borg create --exclude-from /etc/borg/excludes /mnt/backup/repo::daily /homeborg create --compression lz4 <repo>::<archive> <path> — Use LZ4 compression (fast). Options: none, lz4, zstd, zlib, lzma.
borg create --compression lz4 /mnt/backup/repo::home-daily /homeborg create --compression zstd,<level> <repo>::<archive> <path> — Use Zstandard compression at the specified level (1-22). Level 3 is a good default.
borg create --compression zstd,3 /mnt/backup/repo::home-daily /homeborg create -n <repo>::<archive> <path> — Dry run: show what would be archived without actually creating the archive.
borg create -n /mnt/backup/repo::test-dry-run /home/userListing Archives
borg list <repo> — List all archives in the repository.
borg list /mnt/backup/repoborg list --short <repo> — List only archive names, one per line (useful for scripting).
borg list --short /mnt/backup/repoborg list <repo>::<archive> — List all files inside a specific archive.
borg list /mnt/backup/repo::home-2024-01-15borg list <repo>::<archive> --pattern 'sh:<glob>' — List files in an archive matching a shell glob pattern.
borg list /mnt/backup/repo::home-2024-01-15 --pattern 'sh:*.conf'borg list --json <repo> — List archives as JSON (for scripting).
borg list --json /mnt/backup/repo | jq '.archives[-1].name'Extracting Archives
borg extract <repo>::<archive> — Extract the full archive into the current directory.
borg extract /mnt/backup/repo::home-2024-01-15borg extract <repo>::<archive> <path> — Extract only a specific path or file from the archive.
borg extract /mnt/backup/repo::home-2024-01-15 home/user/Documentsborg extract --strip-components <n> <repo>::<archive> — Strip the first n path components when extracting.
borg extract --strip-components 2 /mnt/backup/repo::home-2024-01-15borg extract --dry-run <repo>::<archive> — Preview what would be extracted without actually writing files.
borg extract --dry-run /mnt/backup/repo::home-2024-01-15borg extract --stdout <repo>::<archive> <file> | <command> — Extract a single file and pipe its content to stdout.
borg extract --stdout /mnt/backup/repo::home-2024-01-15 home/user/db.sql | mysql -u root mydbMount Archives (FUSE)
borg mount <repo> <mountpoint> — Mount all archives in the repository as a virtual filesystem (requires FUSE).
borg mount /mnt/backup/repo /mnt/borgborg mount <repo>::<archive> <mountpoint> — Mount a single archive as a virtual filesystem.
borg mount /mnt/backup/repo::home-2024-01-15 /mnt/borgborg umount <mountpoint> — Unmount a previously mounted Borg filesystem.
borg umount /mnt/borgPruning & Deleting
Caution – destructive:
borg prune,borg deleteandborg compactremove archives and data permanently. Always check what gets removed first with--dry-run(and--listforprune).
borg prune --keep-daily <n> --keep-weekly <n> --keep-monthly <n> <repo> — Apply a retention policy to the repository. Archives outside policy are deleted.
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 /mnt/backup/repoborg prune --dry-run --keep-daily 7 --keep-weekly 4 <repo> — Preview which archives would be removed by the retention policy.
borg prune --dry-run --keep-daily 7 --keep-weekly 4 /mnt/backup/repoborg prune --stats --keep-daily 7 <repo> — Prune and show freed space statistics.
borg prune --stats --keep-daily 7 /mnt/backup/repoborg prune --keep-daily 7 --prefix <prefix> <repo> — Apply retention policy only to archives whose names start with the given prefix.
borg prune --keep-daily 7 --prefix 'home-' /mnt/backup/repoborg prune --keep-daily 7 --glob-archives '<pattern>' <repo> — Apply retention policy only to archives matching a glob pattern.
borg prune --keep-daily 7 --glob-archives 'web-*' /mnt/backup/repoborg delete <repo>::<archive> — Delete a specific archive from the repository. Space is freed after compact.
borg delete /mnt/backup/repo::home-2023-01-01borg compact <repo> — Free unused disk space after deleting archives. Run after prune or delete.
borg compact /mnt/backup/repoRepository Information
borg info <repo> — Show statistics about the repository (total size, unique chunks, encryption).
borg info /mnt/backup/repoborg info <repo>::<archive> — Show detailed statistics about a specific archive.
borg info /mnt/backup/repo::home-2024-01-15borg check <repo> — Check the repository for consistency and integrity.
borg check /mnt/backup/repoborg check --verify-data <repo> — Verify all data by decrypting and decompressing every chunk (slow but thorough).
borg check --verify-data /mnt/backup/repoborg check --archives-only <repo> — Check only the archive metadata, not the data chunks.
borg check --archives-only /mnt/backup/repoKey Management
borg key export <repo> <keyfile> — Export the repository encryption key to a file. Store this securely offsite.
borg key export /mnt/backup/repo ~/borg-key-backup.txtborg key import <repo> <keyfile> — Import a previously exported key back into the repository.
borg key import /mnt/backup/repo ~/borg-key-backup.txtborg key change-passphrase <repo> — Change the passphrase used to protect the encryption key.
borg key change-passphrase /mnt/backup/repoEnvironment Variables
export BORG_REPO=<path> — Set the default repository path so it can be omitted from commands.
export BORG_REPO=/mnt/backup/repoexport BORG_PASSPHRASE=<passphrase> — Set the repository passphrase for unattended/automated backups. Caution: visible in plaintext — prefer BORG_PASSCOMMAND.
export BORG_PASSPHRASE=mysecretpasswordexport BORG_PASSCOMMAND=<command> — Run a command and use its stdout as the passphrase.
export BORG_PASSCOMMAND='pass show borg/main'export BORG_RSH='ssh -i <keyfile>' — Use a specific SSH key when connecting to a remote Borg repository.
export BORG_RSH='ssh -i ~/.ssh/borg_backup_key'export BORG_REMOTE_PATH=<path> — Path to the borg executable on the remote server.
export BORG_REMOTE_PATH=/usr/local/bin/borgCommon Recipes
borg create --stats --compression zstd,3 --exclude '/home/*/.cache' <repo>::'{hostname}-{now:%Y-%m-%dT%H:%M}' /home — Production backup: timestamped archive with Zstandard compression and cache exclusion.
borg create --stats --compression zstd,3 --exclude '/home/*/.cache' /mnt/backup/repo::'{hostname}-{now:%Y-%m-%dT%H:%M}' /homeborg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --stats && borg compact — Apply retention policy and compact freed space. Chain with backup in a cron job.
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --stats /mnt/backup/repo && borg compact /mnt/backup/repoborg list --short <repo> | tail -1 — Get the name of the most recent archive.
borg list --short /mnt/backup/repo | tail -1borg create <repo>::<archive> <path> 2>&1 | grep -E '(Duration|Original|Compressed|Deduplicated)' — Create a backup and extract only the size/duration summary from output.
borg create /mnt/backup/repo::daily-$(date +%F) /home 2>&1 | grep -E '(Duration|Original|Compressed|Deduplicated)' Conclusion
BorgBackup combines deduplication, compression and encryption into an efficient, everyday backup solution — especially for large, frequently changing datasets. Treat the passphrase and the exported key with the same care as the repository itself: without them, encrypted archives are lost for good. And always preview destructive steps like prune or delete with --dry-run before compact frees the space permanently.
Further Reading
- BorgBackup documentation — full manual, quick start and FAQ
- BorgBackup on GitHub — source code, releases and issue tracker
Related Commands
- duplicity – encrypted, incremental backups in GnuPG format
- rclone – syncs files with cloud storage services
- rdiff-backup – incremental backups with reversible diffs