restic backup
restic backup is the primary command used to transfer data into a repository. It scans the source paths, breaks files into chunks, deduplicates them against existing data, encrypts the chunks, and saves them as a "snapshot."
Think of backup as creating a "Save Game" for your filesystem. Each time you run it, a new point-in-time snapshot is created. Because of deduplication, only the changes since the last backup take up significant new space.
Basic Syntax
restic backup [flags] PATH [PATH...]
Usage Patterns
# Backup a single directory
restic backup /home/user/documents
# Backup multiple paths in one snapshot
restic backup /etc /var/www /home/user/scripts
# Backup using environment variables (Recommended)
export RESTIC_REPOSITORY="/var/backups/repo"
export RESTIC_PASSWORD_FILE="/etc/restic/password"
restic backup /srv/data
Key Flags
| Flag | Description |
|---|---|
--tag TAG | Add a custom label (e.g., daily, manual, pre-upgrade) |
--host HOSTNAME | Override the default hostname for this snapshot |
--exclude PATTERN | Skip files/dirs matching a pattern (e.g., *.tmp, cache/) |
--iexclude PATTERN | Same as exclude, but case-insensitive |
--exclude-file FILE | Read exclude patterns from a text file |
--files-from FILE | Read a list of paths to back up from a file |
--one-file-system | Do not cross filesystem boundaries (prevents backing up mounts) |
--dry-run / -n | Preview what would be backed up without writing data |
--parent ID | Manually specify the parent snapshot for faster scanning |
Practical Examples
1. Basic Web Server Backup with Tags
Tags allow you to organize and filter snapshots later during restores or cleanup.
restic backup /var/www/html --tag production --tag web
2. Excluding Junk Data
Backing up caches and temporary files wastes space and time.
restic backup /home/user \
--exclude ".cache" \
--exclude "node_modules" \
--exclude "*.tmp" \
--tag home
3. Using a "Files From" List
Useful for backing up a specific list of user directories or configurations.
# backup-list.txt
# /etc/nginx
# /etc/mysql
# /var/lib/mysql-backups
restic backup --files-from backup-list.txt --tag configs
4. Backup a Database Dump (Streaming)
You can stream data directly into Restic via stdin.
mysqldump my_database | restic backup --stdin --stdin-filename db-dump.sql --tag db
backup vs rsync vs rclone
| Behavior | rsync | rclone | restic |
|---|---|---|---|
| Storage Format | Flat Files | Flat Files | Encrypted Blobs |
| History | Overwrites* | Overwrites* | New Snapshot (Deduplicated) |
| Encryption | SSH Only | Optional | Native & Mandatory |
| Remote Support | SSH/RsyncD | 50+ Cloud Providers | Native + Rclone Bridge |
Restic's deduplication is global across the entire repository. If you move a 10GB folder to a different path and backup again, Restic will detect the data already exists and only update the metadata (pointers), using almost no additional storage.
Common Pitfalls
| Pitfall | Consequence | Prevention |
|---|---|---|
| Backing up Live Databases | Corrupt/Inconsistent data. | Always dump the database to a file (sqldump) and back up the dump. |
| Crossing Mounts | Backing up huge network drives or /proc by accident. | Use --one-file-system to stay on the root disk. |
| No Exclude Rules | Repo grows too fast with cache/temp files. | Use --exclude for directories like .cache or tmp. |
| Hardcoding Passwords | Security risk (visible in ps ax or history). | Use RESTIC_PASSWORD_FILE or RESTIC_PASSWORD_COMMAND. |
Examples with Output
1. Standard First Backup
Command:
restic backup /home/user/documents --tag initial
Output:
repository a7b2c9d opened successfully, password is correct
no parent snapshot found, will read all files
Files: 1250 new, 0 changed, 0 unmodified
Dirs: 150 new, 0 changed, 0 unmodified
Added to the repo: 350.210 MiB
processed 1250 files, 350.210 MiB in 0:15
snapshot d8f3e2a1 saved
2. Incremental Backup (No Changes)
Command:
restic backup /home/user/documents --tag daily
Output:
repository a7b2c9d opened successfully, password is correct
using parent snapshot d8f3e2a1
Files: 0 new, 0 changed, 1250 unmodified
Dirs: 0 new, 0 changed, 150 unmodified
Added to the repo: 0 B
processed 1250 files, 350.210 MiB in 0:02
snapshot f9e2d1c0 saved
3. Backup with Exclusions
Command:
restic backup /var/www --exclude "*.log" --exclude "node_modules"
Output:
repository a7b2c9d opened successfully, password is correct
using parent snapshot f9e2d1c0
Files: 50 new, 12 changed, 8000 unmodified
Dirs: 5 new, 2 changed, 400 unmodified
Added to the repo: 45.100 MiB
processed 8062 files, 1.200 GiB in 0:08
snapshot a1b2c3d4 saved
4. Dry Run (Preview)
Command:
restic backup /etc --dry-run
Output:
repository a7b2c9d opened successfully, password is correct
no parent snapshot found, will read all files
Files: 250 new, 0 changed, 0 unmodified
Dirs: 20 new, 0 changed, 0 unmodified
Added to the repo: 12.500 MiB
processed 250 files, 12.500 MiB in 0:01
Would create snapshot: 7c6d5e4f
5. Single File Stream (Stdin)
Command:
mysqldump dbname | restic backup --stdin --stdin-filename dump.sql
Output:
repository a7b2c9d opened successfully, password is correct
no parent snapshot found, will read all files
Files: 1 new, 0 changed, 0 unmodified
Dirs: 0 new, 0 changed, 0 unmodified
Added to the repo: 55.400 MiB
processed 1 files, 55.400 MiB in 0:03
snapshot b2c3d4e5 saved
What's Next?
Check your newly created snapshots with restic snapshots.