Advanced Backup and Restore Examples Using borg, rsync, tar, and restic

Examples include exclude options and advanced, less obvious use cases and options.

1. Borg Backup

Initialize a Borg repository (run once):

borg init --encryption=repokey /path/to/backup/repo

Local Backup Creation with Exclude and Compression Level

borg create --progress \
  --compression lz4 \
  --exclude '*.cache' \
  --exclude '/path/to/source/tmp' \
  --exclude-caches \
  /path/to/backup/repo::backup-$(date +%Y%m%d-%H%M%S) /path/to/source

Notes:

Remote Backup via SSH with Bandwidth Limit and Logging

borg create --progress \
  --remote-path=/usr/local/bin/borg \
  --exclude '*.cache' \
  --exclude '/path/to/source/tmp' \
  --remote-ratelimit=50000 \
  --stats \
  user@remotehost:/path/to/backup/repo::backup-$(date +%Y%m%d-%H%M%S) /path/to/source

Limit remote transfer speed to ~50KB/s with --remote-ratelimit to avoid saturating network.

Restore Specific Files or Directory

borg extract /path/to/backup/repo::backup-YYYYMMDD-HHMMSS path/to/specific/file.txt

Check Repository Integrity

borg check /path/to/backup/repo

Borg: Automated Backup Script + systemd Timer

Create a backup script borg-backup.sh:

#!/bin/bash
REPO="/path/to/backup/repo"
SOURCE="/path/to/source"
EXCLUDES="--exclude '*.cache' --exclude '/tmp' --exclude-caches"

export BORG_PASSPHRASE="YourStrongPassphrase"

borg create --stats --progress --compression lz4 $EXCLUDES \
  $REPO::backup-$(date +%Y%m%d-%H%M%S) $SOURCE

borg prune -v --keep-daily=7 --keep-weekly=4 --keep-monthly=6 $REPO

Make it executable:

chmod +x borg-backup.sh

Create systemd service borg-backup.service:

[Unit]
Description=Borg Backup Service

[Service]
Type=oneshot
ExecStart=/path/to/borg-backup.sh

Create systemd timer borg-backup.timer to run daily at 2:30 AM:

[Unit]
Description=Run Borg Backup daily at 2:30 AM

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

Enable and start timer:

sudo systemctl enable borg-backup.timer
sudo systemctl start borg-backup.timer

2. Tar Backup

Local Backup with Exclude Patterns Using a File

tar czvf backup-$(date +%Y%m%d-%H%M%S).tar.gz \
  --exclude-from='/path/to/exclude-list.txt' \
  /path/to/source

Example exclude-list.txt:

*.cache
tmp
*.log
.git

Remote Backup Streaming with Compression and Verbose Output

ssh user@remotehost "tar czvf - --exclude='*.cache' --exclude='tmp' /path/to/source" \
  > backup-remote-$(date +%Y%m%d-%H%M%S).tar.gz

Restore Single File From Archive

tar xzvf backup-YYYYMMDD-HHMMSS.tar.gz path/to/file.txt -C /path/to/restore

Verify Archive Contents Before Extracting

tar tzvf backup-YYYYMMDD-HHMMSS.tar.gz

Tar: Backup with Exclude & Rotating Archives Script + Cron

Script tar-backup.sh to create compressed backups and keep last 7 archives:

#!/bin/bash
SRC="/path/to/source"
BACKUP_DIR="/path/to/backups"
EXCLUDE_FILE="/path/to/exclude-list.txt"
DATE=$(date +%Y%m%d-%H%M%S)
ARCHIVE="$BACKUP_DIR/backup-$DATE.tar.gz"

tar czvf $ARCHIVE --exclude-from="$EXCLUDE_FILE" $SRC

# Keep only last 7 backups
ls -1tr $BACKUP_DIR/backup-*.tar.gz | head -n -7 | xargs -d '\n' rm -f --

Make executable and schedule with cron at 4:00 AM:

chmod +x tar-backup.sh

0 4 * * * /path/to/tar-backup.sh

3. Rsync Backup

Local Backup with Multiple Exclude Patterns from a File

rsync -a --delete --exclude-from='/path/to/exclude-list.txt' \
  /path/to/source/ /path/to/backup/

Where exclude-list.txt contains one exclude pattern per line, e.g.:

*.cache
tmp/
*.log
.git/

Remote Backup via SSH with Compression and Partial Transfers

rsync -az --partial --progress -e ssh \
  --exclude='*.cache' \
  --exclude='tmp/' \
  /path/to/source/ user@remotehost:/path/to/backup/

-z compresses data during transfer, --partial keeps partially transferred files on failure for resume.

Incremental Backup with Hard Links

rsync -a --link-dest=/path/to/previous/backup \
  /path/to/source/ /path/to/new/backup/

This creates a new backup directory, hard-linking unchanged files to save space (good for incremental backups).

Dry Run to Test Command

rsync -a --dry-run --exclude='*.cache' /path/to/source/ /path/to/backup/

Rsync: Incremental Backup Script with Exclude File & Cron

Example rsync-incremental.sh:

#!/bin/bash
SRC="/path/to/source/"
DEST="/path/to/backup/"
PREV_BACKUP="/path/to/previous/backup/"
EXCLUDE_FILE="/path/to/exclude-list.txt"

rsync -a --delete --exclude-from="$EXCLUDE_FILE" --link-dest="$PREV_BACKUP" \
  "$SRC" "$DEST"/backup-$(date +%Y%m%d-%H%M%S)/

Make executable:

chmod +x rsync-incremental.sh

Add cron job to run daily at 3:00 AM:

0 3 * * * /path/to/rsync-incremental.sh

4. Restic Backup

Initialize repository (local or remote):

restic init -r /path/to/repo
# or remote
restic init -r sftp:user@remotehost:/path/to/repo

Backup with Excludes and Tagging

restic -r /path/to/repo backup \
  --exclude '*.cache' \
  --exclude '/path/to/source/tmp' \
  --tag important,weekly \
  /path/to/source

Tags help categorize snapshots for easier filtering and cleanup.

Backup with Limit Bandwidth and CPU Usage

restic -r /path/to/repo backup /path/to/source \
  --limit-upload 1000 \
  --limit-download 1000 \
  --low-priority

Limits upload/download bandwidth to 1000 KB/s and lowers CPU priority.

Restore Specific Files or Folders from Snapshot

restic -r /path/to/repo restore latest --target /path/to/restore --include path/to/file_or_dir

Forget Old Snapshots and Prune Repository

restic -r /path/to/repo forget --keep-last 5 --prune

Keeps last 5 snapshots, removes older, and prunes repository to free space.

Check Repository Integrity

restic -r /path/to/repo check

Restic: Automated Backup with Prune and systemd

Script restic-backup.sh:

#!/bin/bash
export RESTIC_REPOSITORY="/path/to/restic/repo"
export RESTIC_PASSWORD="YourResticPassword"

restic backup /path/to/source \
  --exclude '*.cache' \
  --exclude '/tmp'

# Remove old snapshots but keep recent backups
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

Make executable:

chmod +x restic-backup.sh

systemd service restic-backup.service:

[Unit]
Description=Restic Backup Service

[Service]
Type=oneshot
ExecStart=/path/to/restic-backup.sh

systemd timer restic-backup.timer to run every day at 1:00 AM:

[Unit]
Description=Run Restic Backup daily at 1:00 AM

[Timer]
OnCalendar=*-*-* 01:00:00
Persistent=true

[Install]
WantedBy=timers.target

Enable and start timer:

sudo systemctl enable restic-backup.timer
sudo systemctl start restic-backup.timer

Additional Tips