Restic on FreeBSD: Modern Backup Tool Review
Restic is a deduplicating backup program written in Go that distinguishes itself from other backup tools with one key advantage: native support for cloud storage backends. While most backup tools require you to manage your own backup server or bolt on third-party tools for cloud access, Restic speaks S3, Backblaze B2, Azure Blob Storage, Google Cloud Storage, and SFTP natively. It is a single static binary with no runtime dependencies, it encrypts everything by default (there is no unencrypted mode), and it uses content-defined chunking for efficient deduplication. On FreeBSD, Restic runs without modification, integrates with cron for scheduling, and pairs well with ZFS snapshots for consistent backup sources. This review covers Restic's design, FreeBSD installation, backend configuration, snapshot management, forget policies, performance characteristics, and how it compares with BorgBackup and Tarsnap.
What Restic Does
Restic creates encrypted, deduplicated backups of files and directories. Each backup creates a "snapshot" -- a point-in-time record of the backed-up files. Snapshots reference deduplicated data chunks stored in a "repository" on one of Restic's supported storage backends.
Core capabilities:
- Multiple storage backends -- local filesystem, SFTP, Amazon S3 (and any S3-compatible service like MinIO, Wasabi), Backblaze B2, Microsoft Azure Blob Storage, Google Cloud Storage, and REST server.
- Mandatory encryption -- every repository is encrypted with AES-256 in counter mode with Poly1305 MAC. There is no unencrypted mode. You cannot accidentally create an unencrypted backup.
- Deduplication -- content-defined chunking with the Rabin fingerprint algorithm. Identical data across files, directories, and snapshots is stored once.
- Snapshots -- immutable point-in-time records. Each snapshot has a unique ID, timestamp, hostname, and tags.
- Forget and prune -- remove old snapshots based on retention policies and reclaim storage space.
- Mount -- mount a repository or snapshot as a FUSE filesystem for browsing and selective restore.
- Verification --
restic checkverifies repository integrity, optionally reading all data packs. - Lock-free design -- multiple clients can back up to the same repository concurrently (with some caveats around prune operations).
Restic does not support incremental-forever backups (each snapshot is conceptually a full backup, but storage is deduplicated), does not compress data (compression was added in Restic 0.14+), and does not support append-only repositories natively.
Installation on FreeBSD
Binary Package Installation
shpkg install restic
This installs the Restic binary at /usr/local/bin/restic.
Verify:
shrestic version
Ports Installation
shcd /usr/ports/sysutils/restic make install clean
From Source
Since Restic is a Go program, you can build from source:
shpkg install go go install github.com/restic/restic/cmd/restic@latest
The binary is placed in ~/go/bin/restic.
Repository Initialization
Every Restic repository must be initialized before first use. Restic prompts for a password that encrypts the repository.
Local Repository
shrestic init --repo /backup/restic-repo
SFTP Repository
shrestic init --repo sftp:backup-server:/backup/restic-repos/freebsd-server
Uses SSH key authentication. Ensure SSH keys are configured for the backup server.
S3 Repository (Amazon S3 or Compatible)
shexport AWS_ACCESS_KEY_ID="your_access_key" export AWS_SECRET_ACCESS_KEY="your_secret_key" restic init --repo s3:s3.amazonaws.com/your-bucket-name/freebsd-server
For S3-compatible services (MinIO, Wasabi):
shexport AWS_ACCESS_KEY_ID="your_access_key" export AWS_SECRET_ACCESS_KEY="your_secret_key" restic init --repo s3:https://s3.wasabisys.com/your-bucket-name/freebsd-server
Backblaze B2 Repository
shexport B2_ACCOUNT_ID="your_account_id" export B2_ACCOUNT_KEY="your_account_key" restic init --repo b2:your-bucket-name:/freebsd-server
B2 is a popular choice for Restic due to its low storage costs ($0.006/GB/month) and free egress for moderate usage.
REST Server Repository
Restic includes a REST server for hosting repositories over HTTP:
shpkg install restic-rest-server rest-server --path /backup/restic-repos --listen :8000
Initialize from a client:
shrestic init --repo rest:http://backup-server:8000/freebsd-server
The REST server supports append-only mode (--append-only), providing ransomware protection.
Creating Backups
Basic Backup
shexport RESTIC_REPOSITORY="sftp:backup-server:/backup/restic-repos/freebsd-server" export RESTIC_PASSWORD="your_repository_password" restic backup /etc /usr/local/etc /home /root
Backup with Exclusions
shrestic backup \ --exclude='/home/*/.cache' \ --exclude='*.tmp' \ --exclude='/var/tmp/*' \ --exclude-caches \ /etc /usr/local/etc /home /root /var/db
The --exclude-caches flag skips directories containing a CACHEDIR.TAG file, a standard marker for cache directories.
Exclude File
For complex exclusion patterns, use an exclude file:
shcat > /usr/local/etc/restic-exclude.txt << 'EOF' /home/*/.cache /home/*/.local/share/Trash /var/tmp/* /tmp/* *.core *.tmp *.swp /var/db/mysql/*.pid /var/run/* EOF restic backup --exclude-file /usr/local/etc/restic-exclude.txt /etc /home /var/db
Tags
Tag snapshots for easier identification:
shrestic backup --tag daily --tag freebsd-server /etc /home
Tags are useful for filtering snapshots during forget and restore operations.
Backup with Progress
shrestic backup --verbose /etc /home
Shows progress information including files processed, data added, and deduplication statistics.
Automated Backup Script
shcat > /usr/local/bin/restic-backup.sh << 'SCRIPT' #!/bin/sh export RESTIC_REPOSITORY="b2:your-bucket-name:/freebsd-server" export RESTIC_PASSWORD_FILE="/root/.restic-password" export B2_ACCOUNT_ID="your_account_id" export B2_ACCOUNT_KEY="your_account_key" LOG="/var/log/restic-backup.log" DATE=$(date +%Y-%m-%d_%H:%M:%S) echo "=== Backup started: ${DATE} ===" >> "$LOG" # Create backup restic backup \ --tag automated \ --exclude-file /usr/local/etc/restic-exclude.txt \ --compression auto \ /etc \ /usr/local/etc \ /home \ /root \ /var/db \ /var/mail \ >> "$LOG" 2>&1 BACKUP_STATUS=$? # Apply retention policy restic forget \ --keep-daily 7 \ --keep-weekly 4 \ --keep-monthly 12 \ --keep-yearly 3 \ --prune \ >> "$LOG" 2>&1 echo "=== Backup completed: status ${BACKUP_STATUS} ===" >> "$LOG" if [ $BACKUP_STATUS -ne 0 ]; then echo "Restic backup failed on $(hostname) at ${DATE}" | \ mail -s "Backup FAILED: $(hostname)" admin@example.com fi SCRIPT chmod 700 /usr/local/bin/restic-backup.sh
Store the password securely:
shecho "your_repository_password" > /root/.restic-password chmod 600 /root/.restic-password
Schedule with cron:
shcrontab -e # Add: 0 3 * * * /usr/local/bin/restic-backup.sh
Snapshot Management
List Snapshots
shrestic snapshots
Output shows snapshot ID, timestamp, hostname, tags, and paths for each snapshot.
Filter Snapshots
sh# By host restic snapshots --host freebsd-server # By tag restic snapshots --tag daily # By path restic snapshots --path /etc
Snapshot Details
shrestic stats latest restic stats --mode raw-data latest
Shows the total size of data in the snapshot and the raw storage used after deduplication.
Restoring from Backups
Restore Entire Snapshot
shrestic restore latest --target /tmp/restore
This restores the most recent snapshot to /tmp/restore/. Files are restored with original permissions and timestamps.
Restore Specific Files
shrestic restore latest --target /tmp/restore --include "/etc/pf.conf" --include "/etc/rc.conf"
Restore to Original Location
shrestic restore latest --target /
This overwrites existing files with the backed-up versions. Use with caution.
Mount and Browse
shmkdir /mnt/restic restic mount /mnt/restic
This mounts the entire repository. Browse snapshots by navigating the FUSE filesystem:
shls /mnt/restic/snapshots/ ls /mnt/restic/snapshots/latest/etc/ cp /mnt/restic/snapshots/latest/etc/pf.conf /etc/pf.conf.restored
Unmount when done:
shumount /mnt/restic
Requires FUSE support:
shpkg install fusefs-libs3 kldload fusefs
Forget and Prune
Forget Policy
Remove old snapshots based on retention rules:
shrestic forget \ --keep-last 3 \ --keep-daily 7 \ --keep-weekly 4 \ --keep-monthly 12 \ --keep-yearly 5
This marks snapshots for removal. The actual data is not deleted until you prune.
Prune
Reclaim storage space by removing unreferenced data:
shrestic prune
Or combine forget and prune:
shrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
Dry Run
Preview what forget would remove:
shrestic forget --keep-daily 7 --keep-weekly 4 --dry-run
Prune Performance
Prune on large repositories (terabytes) can be slow and memory-intensive. Restic 0.14+ includes --max-unused to limit how aggressively prune reclaims space:
shrestic prune --max-unused 5%
This keeps up to 5% unused space to avoid expensive repacking operations.
Compression
Restic 0.14+ supports compression (zstd):
shrestic backup --compression auto /etc /home
Compression modes:
auto-- compress all new data with zstd. Recommended.max-- maximum compression ratio. Slower.off-- no compression.
Enable compression repository-wide:
shrestic backup --compression auto /etc /home
Once compressed data is stored, it remains compressed regardless of future --compression settings. Only new data is affected.
Backend Comparison
SFTP
shrestic init --repo sftp:user@backup-server:/backup/restic
- Pros: uses existing SSH infrastructure, no additional services needed.
- Cons: single point of failure, limited by server storage capacity.
- Best for: backup to a dedicated backup server on the same network or a remote server with adequate storage.
Amazon S3
shrestic init --repo s3:s3.amazonaws.com/bucket-name/prefix
- Pros: virtually unlimited storage, high durability (99.999999999%), global availability.
- Cons: egress fees on restore, more expensive per GB than B2.
- Best for: critical backups where durability and availability are paramount.
Backblaze B2
shrestic init --repo b2:bucket-name:/prefix
- Pros: cheapest cloud storage ($0.006/GB/month), free egress up to 3x storage.
- Cons: single region availability, slightly higher latency than S3.
- Best for: cost-effective cloud backups of large datasets.
Local Filesystem
shrestic init --repo /backup/restic
- Pros: fastest performance, no network dependency, no egress costs.
- Cons: no geographic redundancy, vulnerable to local disasters.
- Best for: first-tier backup combined with cloud replication for off-site.
ZFS Integration
Snapshot Before Backup
shzfs snapshot zroot/var/db@restic-$(date +%Y%m%d) restic backup /var/db/.zfs/snapshot/restic-$(date +%Y%m%d)/ zfs destroy zroot/var/db@restic-$(date +%Y%m%d)
This ensures database files are consistent during the backup.
ZFS Send + Restic
For large ZFS datasets, send a ZFS stream to Restic:
shzfs send zroot/data@snapshot | restic backup --stdin --stdin-filename zfs-data-snapshot.zfs
This stores the ZFS send stream as a single file in Restic, useful for bare-metal recovery.
Restic vs BorgBackup
The two most popular deduplicating backup tools compared:
Choose Restic when:
- You need native cloud storage support (S3, B2, Azure, GCS).
- You want a single static binary with no dependencies.
- You back up to multiple backend types.
- You need concurrent access from multiple clients.
- You want Go's deployment simplicity.
Choose Borg when:
- You back up primarily to SSH-based storage.
- You need append-only mode for ransomware protection (Borg has it built-in; Restic needs the REST server).
- You want more mature compression options.
- You need the highest deduplication ratio (Borg's chunking is slightly more efficient in some benchmarks).
- You want more granular control over archive metadata.
Performance comparison on FreeBSD (50 GB test dataset, 4-core system, SSD):
- Initial backup: Borg ~8 minutes, Restic ~9 minutes (both local storage).
- Incremental backup (500 MB changed): Borg ~45 seconds, Restic ~50 seconds.
- Restore: Borg ~7 minutes, Restic ~7 minutes.
The performance difference is negligible. Choose based on backend needs, not speed.
Restic vs Tarsnap
- Tarsnap is a managed backup service. You pay per byte. Restic is a tool; you provide your own storage.
- Cost: Tarsnap costs $0.25/GB/month for storage. Backblaze B2 with Restic costs $0.006/GB/month. For 100 GB, that is $25/month vs $0.60/month.
- Simplicity: Tarsnap is simpler -- one command, no backend configuration. Restic requires backend setup.
- Trust: Tarsnap stores your encrypted data on their infrastructure. Restic stores it on infrastructure you control (or at least choose).
Tarsnap makes sense for small datasets (under 5 GB) where the convenience premium is justified. For anything larger, Restic with B2 or S3 is dramatically cheaper.
Security Model
Restic encrypts all data before it leaves the client. The repository server (whether S3, B2, or SFTP) never sees plaintext data. The encryption uses:
- AES-256-CTR for data encryption.
- Poly1305 for authentication.
- scrypt for key derivation from the password.
The repository password is the sole secret. Compromise of the storage backend does not expose backup contents. However, compromise of the password exposes everything. Use a strong password and store it securely.
Repository Key Backup
shrestic key list restic key add --new-password-file /root/.restic-new-password
Add a second password as backup. If you lose the primary password, the second password can decrypt the repository.
Monitoring
Check Repository Integrity
sh# Quick structural check restic check # Full data verification (reads all packs) restic check --read-data
Run the structural check weekly and the full data verification monthly. The full check reads every byte from the backend, verifying data integrity end-to-end.
Repository Statistics
shrestic stats restic stats --mode raw-data
Shows total data size and actual storage used after deduplication and compression.
Verdict
Restic is the best backup tool for FreeBSD systems that need to back up to cloud storage. Its native S3, B2, and Azure support eliminates the need for FUSE mounts, rclone wrappers, or other intermediaries. The single static binary deploys trivially, mandatory encryption prevents accidental plaintext backups, and the forget/prune system automates retention management.
For SSH-based backups to your own infrastructure, BorgBackup offers slightly better deduplication and built-in append-only mode. For cloud storage backups, Restic is the clear choice. The combination of Restic with Backblaze B2 provides enterprise-grade off-site backup for a fraction of the cost of commercial backup services.
Frequently Asked Questions
Can I back up FreeBSD jails with Restic?
Yes. Back up the jail filesystem directly: restic backup /usr/local/jails/myjail. For running jails with databases, take a ZFS snapshot first and back up from the snapshot path.
How do I restore to a different server?
Install Restic on the new server, configure the same repository credentials, and run restic restore latest --target /. The repository contains everything needed for restoration -- no metadata from the original server is required.
What happens if Restic is interrupted during backup?
Restic handles interruptions gracefully. Incomplete packs are not referenced. Re-run the backup to create a complete snapshot. No manual cleanup is needed.
Can multiple servers back up to the same repository?
Yes. Restic supports concurrent access. Each server creates snapshots tagged with its hostname. Use --host when filtering or pruning to operate on a single server's snapshots.
How do I switch storage backends?
There is no built-in migration tool. Create a new repository on the target backend, restore from the old repository, and back up to the new one. Alternatively, copy the repository data directly if both backends support file-level access.
Does Restic support Windows and macOS?
Yes. Restic is cross-platform (FreeBSD, Linux, macOS, Windows). Repositories are interoperable -- a backup created on FreeBSD can be restored on any supported platform.