Immich Offsite Backup with restic: A Doc-Based Guide
Doc-based, not yet hands-on tested. This guide is written from the official documentation and has not yet been tested hands-on by us. Check the current official docs before running anything.
Disclosure: some links on this page may become affiliate links. If you buy through one, we may earn a commission at no extra cost to you. See our affiliate disclosure.
Pinned versions: Immich v3.3.5 (https://github.com/immich-app/immich/releases/tag/v3.3.5) and restic v0.19.1 (latest GitHub release, published 2026-07-05 17:13 JST / 2026-07-05 08:13 UTC — https://github.com/restic/restic/releases/tag/v0.19.1). Last checked: 2026-10-24.
Transparency note: This guide is based on the official documentation linked below. It was not hands-on tested by us. Commands are copied from the official docs as of the date above; always check the current docs before running them.
The Immich docs recommend a 3-2-1 backup strategy and say they only show what to back up: "You still need to take care of using an actual backup tool" (Backup and Restore). This guide fills that gap with restic, an encrypted, deduplicating backup tool, sending your Immich files to a second machine over SFTP (for example a small VPS).
What to back up
From the Immich docs: back up all of UPLOAD_LOCATION. Immich writes its automatic database dumps to UPLOAD_LOCATION/backups, so one restic backup of UPLOAD_LOCATION captures both the photos and the database dumps. Backup ordering (from the Immich docs): the database and asset files can get out of sync. The docs say "the best way of dealing with this is to stop the immich-server container while you take a backup." If stopping isn't an option, they recommend backing up the database first and the filesystem second. Since restic runs after the nightly dump, this guide follows that second order; for a fully consistent copy, stop immich-server during the restic run. See our Immich backup and restore guide for the folder list and the restore drill.
Pick an offsite target
restic supports many repository types, including a local folder, SFTP, a REST server, Amazon S3 and S3-compatible storage, Backblaze B2, Azure, Google Cloud Storage, and others via rclone (Preparing a new repository). This guide uses SFTP because any Linux VPS with SSH can act as the target.
restic's docs say SFTP needs passwordless (key-based) SSH login, "since automatic backups are not possible if the server prompts for credentials."
Step 1: Create the repository
Run on your Immich server (replace user, host and path):
restic -r sftp:user@host:/srv/restic-repo initYou'll be asked for a repository password twice.
⚠️ Caution: restic's docs warn: "Losing your password means that your data is irrecoverably lost." Store it in your password manager and somewhere outside the server you're backing up.
For scheduled runs, restic can read the password from a file with --password-file (or RESTIC_PASSWORD_FILE) and the repository from RESTIC_REPOSITORY.
Step 2: Back up UPLOAD_LOCATION
restic -r sftp:user@host:/srv/restic-repo --verbose backup /path/to/UPLOAD_LOCATIONReplace /path/to/UPLOAD_LOCATION with the value from your Immich .env file. Later runs only upload changed data. restic's docs also note that SFTP servers can drop idle connections during long runs over unchanged data, and suggest adding to the client's ~/.ssh/config:
ServerAliveInterval 60
ServerAliveCountMax 240Step 3: Keep a sensible history
restic removes old snapshots with forget and frees space with prune. The --prune switch does both in one step. The docs use this policy as an example:
restic -r sftp:user@host:/srv/restic-repo forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --pruneThat keeps one snapshot per day for the last 7 days, one per week for 5 weeks, and one per month for 12 months. Pick your own numbers. *(The docs' example also includes --keep-yearly 75; we left it out to keep it simple.)*
Step 4: Check and test-restore
List snapshots and verify the repository structure:
restic -r sftp:user@host:/srv/restic-repo snapshots
restic -r sftp:user@host:/srv/restic-repo checkrestic's docs recommend running check regularly. A backup only counts once you have restored from it, so restore the latest snapshot to a scratch folder:
restic -r sftp:user@host:/srv/restic-repo restore latest --target /tmp/restore⚠️ Caution: never restore straight over your live
UPLOAD_LOCATION. Restore to a separate folder or VM, then follow the Immich restore drill in our backup and restore guide.
Automating it
Run steps 2 and 3 on a schedule (cron or a systemd timer) after Immich's nightly database dump (2:00 AM by default, per the Immich docs). Use --password-file so the job doesn't prompt. Check the job's output now and then: a silent failure is the most common way backups quietly stop working. (Recommendation: our advice, not from the docs, apart from the 2:00 AM default.)
Next step
Need somewhere to send the backups? See Cheapest VPS for Immich or Nextcloud.
Sources
- https://docs.immich.app/administration/backup-and-restore
- https://github.com/immich-app/immich/releases/tag/v3.3.5
- https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html
- https://restic.readthedocs.io/en/stable/040_backup.html
- https://restic.readthedocs.io/en/stable/045_working_with_repos.html
- https://restic.readthedocs.io/en/stable/050_restore.html
- https://restic.readthedocs.io/en/stable/060_forget.html
- https://github.com/restic/restic/releases/tag/v0.19.1