# 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.

Source: https://www.jpkc.com/db/en/cheatsheets/backup-sync/borgbackup/

<!-- PROSE:intro -->
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.
<!-- PROSE:intro:end -->

## Repository Initialization

`borg init --encryption=repokey <path>` — Initialize a new local repository with encryption. The key is stored in the repository itself.

```bash
borg init --encryption=repokey /mnt/backup/myrepo
```

`borg init --encryption=keyfile <path>` — Initialize a repository with encryption. The key is stored in ~/.config/borg/keys (safer for offsite repos).

```bash
borg init --encryption=keyfile /mnt/backup/myrepo
```

`borg init --encryption=none <path>` — Initialize a repository without encryption. Not recommended for sensitive data.

```bash
borg init --encryption=none /tmp/testrepo
```

`borg init --encryption=repokey-blake2 <path>` — Initialize with repokey encryption using BLAKE2b (faster than SHA-256 on modern hardware).

```bash
borg init --encryption=repokey-blake2 /mnt/backup/myrepo
```

`borg init --encryption=repokey <user>@<host>:<path>` — Initialize a repository on a remote server via SSH.

```bash
borg init --encryption=repokey user@server.com:/backup/repo
```

## Creating Archives

`borg create <repo>::<archive> <path>` — Create a new archive in the repository. Archive names must be unique.

```bash
borg create /mnt/backup/repo::home-2024-01-15 /home/user
```

`borg create <repo>::'{hostname}-{now:%Y-%m-%d}' <path>` — Create an archive with an automatic name using placeholders for hostname and date.

```bash
borg create /mnt/backup/repo::'{hostname}-{now:%Y-%m-%d}' /home/user
```

`borg create --stats <repo>::<archive> <path>` — Show backup statistics (original size, compressed size, deduplicated size) after completion.

```bash
borg create --stats /mnt/backup/repo::backup-today /home
```

`borg create --progress <repo>::<archive> <path>` — Show progress during backup creation.

```bash
borg create --progress /mnt/backup/repo::daily-backup /home
```

`borg create --exclude <pattern> <repo>::<archive> <path>` — Exclude files matching a pattern from the archive.

```bash
borg create --exclude '/home/*/.cache' /mnt/backup/repo::home-backup /home
```

`borg create --exclude-from <file> <repo>::<archive> <path>` — Read exclude patterns from a file.

```bash
borg create --exclude-from /etc/borg/excludes /mnt/backup/repo::daily /home
```

`borg create --compression lz4 <repo>::<archive> <path>` — Use LZ4 compression (fast). Options: none, lz4, zstd, zlib, lzma.

```bash
borg create --compression lz4 /mnt/backup/repo::home-daily /home
```

`borg create --compression zstd,<level> <repo>::<archive> <path>` — Use Zstandard compression at the specified level (1-22). Level 3 is a good default.

```bash
borg create --compression zstd,3 /mnt/backup/repo::home-daily /home
```

`borg create -n <repo>::<archive> <path>` — Dry run: show what would be archived without actually creating the archive.

```bash
borg create -n /mnt/backup/repo::test-dry-run /home/user
```

## Listing Archives

`borg list <repo>` — List all archives in the repository.

```bash
borg list /mnt/backup/repo
```

`borg list --short <repo>` — List only archive names, one per line (useful for scripting).

```bash
borg list --short /mnt/backup/repo
```

`borg list <repo>::<archive>` — List all files inside a specific archive.

```bash
borg list /mnt/backup/repo::home-2024-01-15
```

`borg list <repo>::<archive> --pattern 'sh:<glob>'` — List files in an archive matching a shell glob pattern.

```bash
borg list /mnt/backup/repo::home-2024-01-15 --pattern 'sh:*.conf'
```

`borg list --json <repo>` — List archives as JSON (for scripting).

```bash
borg list --json /mnt/backup/repo | jq '.archives[-1].name'
```

## Extracting Archives

`borg extract <repo>::<archive>` — Extract the full archive into the current directory.

```bash
borg extract /mnt/backup/repo::home-2024-01-15
```

`borg extract <repo>::<archive> <path>` — Extract only a specific path or file from the archive.

```bash
borg extract /mnt/backup/repo::home-2024-01-15 home/user/Documents
```

`borg extract --strip-components <n> <repo>::<archive>` — Strip the first n path components when extracting.

```bash
borg extract --strip-components 2 /mnt/backup/repo::home-2024-01-15
```

`borg extract --dry-run <repo>::<archive>` — Preview what would be extracted without actually writing files.

```bash
borg extract --dry-run /mnt/backup/repo::home-2024-01-15
```

`borg extract --stdout <repo>::<archive> <file> | <command>` — Extract a single file and pipe its content to stdout.

```bash
borg extract --stdout /mnt/backup/repo::home-2024-01-15 home/user/db.sql | mysql -u root mydb
```

## Mount Archives (FUSE)

`borg mount <repo> <mountpoint>` — Mount all archives in the repository as a virtual filesystem (requires FUSE).

```bash
borg mount /mnt/backup/repo /mnt/borg
```

`borg mount <repo>::<archive> <mountpoint>` — Mount a single archive as a virtual filesystem.

```bash
borg mount /mnt/backup/repo::home-2024-01-15 /mnt/borg
```

`borg umount <mountpoint>` — Unmount a previously mounted Borg filesystem.

```bash
borg umount /mnt/borg
```

## Pruning & Deleting

> **Caution – destructive:** `borg prune`, `borg delete` and `borg compact` remove archives and data permanently. Always check what gets removed first with `--dry-run` (and `--list` for `prune`).

`borg prune --keep-daily <n> --keep-weekly <n> --keep-monthly <n> <repo>` — Apply a retention policy to the repository. Archives outside policy are deleted.

```bash
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 /mnt/backup/repo
```

`borg prune --dry-run --keep-daily 7 --keep-weekly 4 <repo>` — Preview which archives would be removed by the retention policy.

```bash
borg prune --dry-run --keep-daily 7 --keep-weekly 4 /mnt/backup/repo
```

`borg prune --stats --keep-daily 7 <repo>` — Prune and show freed space statistics.

```bash
borg prune --stats --keep-daily 7 /mnt/backup/repo
```

`borg prune --keep-daily 7 --prefix <prefix> <repo>` — Apply retention policy only to archives whose names start with the given prefix.

```bash
borg prune --keep-daily 7 --prefix 'home-' /mnt/backup/repo
```

`borg prune --keep-daily 7 --glob-archives '<pattern>' <repo>` — Apply retention policy only to archives matching a glob pattern.

```bash
borg prune --keep-daily 7 --glob-archives 'web-*' /mnt/backup/repo
```

`borg delete <repo>::<archive>` — Delete a specific archive from the repository. Space is freed after compact.

```bash
borg delete /mnt/backup/repo::home-2023-01-01
```

`borg compact <repo>` — Free unused disk space after deleting archives. Run after prune or delete.

```bash
borg compact /mnt/backup/repo
```

## Repository Information

`borg info <repo>` — Show statistics about the repository (total size, unique chunks, encryption).

```bash
borg info /mnt/backup/repo
```

`borg info <repo>::<archive>` — Show detailed statistics about a specific archive.

```bash
borg info /mnt/backup/repo::home-2024-01-15
```

`borg check <repo>` — Check the repository for consistency and integrity.

```bash
borg check /mnt/backup/repo
```

`borg check --verify-data <repo>` — Verify all data by decrypting and decompressing every chunk (slow but thorough).

```bash
borg check --verify-data /mnt/backup/repo
```

`borg check --archives-only <repo>` — Check only the archive metadata, not the data chunks.

```bash
borg check --archives-only /mnt/backup/repo
```

## Key Management

`borg key export <repo> <keyfile>` — Export the repository encryption key to a file. Store this securely offsite.

```bash
borg key export /mnt/backup/repo ~/borg-key-backup.txt
```

`borg key import <repo> <keyfile>` — Import a previously exported key back into the repository.

```bash
borg key import /mnt/backup/repo ~/borg-key-backup.txt
```

`borg key change-passphrase <repo>` — Change the passphrase used to protect the encryption key.

```bash
borg key change-passphrase /mnt/backup/repo
```

## Environment Variables

`export BORG_REPO=<path>` — Set the default repository path so it can be omitted from commands.

```bash
export BORG_REPO=/mnt/backup/repo
```

`export BORG_PASSPHRASE=<passphrase>` — Set the repository passphrase for unattended/automated backups. Caution: visible in plaintext — prefer `BORG_PASSCOMMAND`.

```bash
export BORG_PASSPHRASE=mysecretpassword
```

`export BORG_PASSCOMMAND=<command>` — Run a command and use its stdout as the passphrase.

```bash
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.

```bash
export BORG_RSH='ssh -i ~/.ssh/borg_backup_key'
```

`export BORG_REMOTE_PATH=<path>` — Path to the borg executable on the remote server.

```bash
export BORG_REMOTE_PATH=/usr/local/bin/borg
```

## Common 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.

```bash
borg create --stats --compression zstd,3 --exclude '/home/*/.cache' /mnt/backup/repo::'{hostname}-{now:%Y-%m-%dT%H:%M}' /home
```

`borg 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.

```bash
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --stats /mnt/backup/repo && borg compact /mnt/backup/repo
```

`borg list --short <repo> | tail -1` — Get the name of the most recent archive.

```bash
borg list --short /mnt/backup/repo | tail -1
```

`borg create <repo>::<archive> <path> 2>&1 | grep -E '(Duration|Original|Compressed|Deduplicated)'` — Create a backup and extract only the size/duration summary from output.

```bash
borg create /mnt/backup/repo::daily-$(date +%F) /home 2>&1 | grep -E '(Duration|Original|Compressed|Deduplicated)'
```

<!-- PROSE:outro -->
## 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](https://borgbackup.readthedocs.io/) — full manual, quick start and FAQ
- [BorgBackup on GitHub](https://github.com/borgbackup/borg) — source code, releases and issue tracker
<!-- PROSE:outro:end -->

## Related Commands

- [duplicity](https://www.jpkc.com/db/en/cheatsheets/backup-sync/duplicity/) – encrypted, incremental backups in GnuPG format
- [rclone](https://www.jpkc.com/db/en/cheatsheets/backup-sync/rclone/) – syncs files with cloud storage services
- [rdiff-backup](https://www.jpkc.com/db/en/cheatsheets/backup-sync/rdiff-backup/) – incremental backups with reversible diffs

