We earn commissions when you shop through the links below. Full disclosure →
A single-binary command-line backup program: deduplicated (content-defined chunking), encrypted (AES-256 with Poly1305-AES) and, since repository format v2, zstd-compressed snapshots, written straight to local disk, SFTP, S3-compatible storage, Backblaze B2, Azure, Google Cloud, its own REST server or anything rclone reaches. No daemon and no GUI upstream: you schedule it with cron or a systemd timer.
Pick restic when you want server backups you can read as a script: one BSD-2-Clause Go binary that writes encrypted (AES-256 with Poly1305-AES), deduplicated snapshots to SFTP, S3-compatible storage, Backblaze B2, Azure, Google Cloud, its own REST server or anything rclone reaches. Repository format v2, the default since 0.14.0, compresses with zstd automatically. Retention is a `restic forget --keep-*` line, so the whole backup policy fits in a cron job or systemd timer. Upstream has no GUI; Backrest is a third-party web UI on top of it. If you would rather have stored policies, automatic maintenance and a web UI, or back up many machines through one server, Kopia is the fit.
What you need
Any VPS with at least 512 MB of RAM
A domain you control — most self-hosted setups need HTTPS in front of them
Paid link — we earn a commission if you shop through it.
Install
Run these commands on your server:
# restic — official release binary (restic.readthedocs.io, Installation → Official binaries); distro packages can lag behindcurl -fsSL -o restic.bz2 https://github.com/restic/restic/releases/download/v0.19.1/restic_0.19.1_linux_amd64.bz2sudo apt-get install -y bzip2 # bunzip2 is not in the stock Ubuntu 26.04 cloud imagebunzip2 restic.bz2 && sudo install -m 0755 restic /usr/local/bin/restic# from here on, run as root (sudo -i): the password file and the backed-up paths are root-owned# the repository lives off the box: here an S3-compatible bucket (sftp:user@host:/srv/restic-repo and rest:https://... work the same way)export AWS_ACCESS_KEY_ID=<KEY_ID> AWS_SECRET_ACCESS_KEY=<SECRET>export RESTIC_REPOSITORY=s3:https://S3_ENDPOINT/BUCKET RESTIC_PASSWORD_FILE=/root/.restic-passwordopenssl rand -base64 32 > /root/.restic-password && chmod 600 /root/.restic-passwordrestic initrestic backup /etc /srvrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune# lose the password file and the backups are unreadable: keep a copy somewhere other than this server# restic has no scheduler: run backup + forget from cron or a systemd timer, and restic check after pruning
restic does exactly what you tell it and nothing on its own, so four things in its docs matter before you rely on it:
non-negotiableThe password is the only way in. The quick start says losing it means your data is "irrecoverably lost", so keep a copy of the password file away from the server it protects. restic key add lets you add a second password as a fallback.
non-negotiableNothing runs on a schedule. Upstream documents no scheduler or daemon: you run restic backup, restic forget --prune and restic check from cron or a systemd timer, and you have to notice yourself when a run fails.
non-negotiableprune takes an exclusive lock: the docs warn "the repository is locked and backups cannot be completed" while it runs, so give it a window away from your backup jobs. A client that can write to the repository can also delete from it; use rest-server --append-only or storage-side object lock if a compromised host must not wipe its own backups.
non-negotiablerestic copies files, not databases. Dump databases before the backup, or stream the dump in with restic backup --stdin-from-command -- <dump command>. In Docker, set a fixed --hostname, because upstream says restic "relies on the hostname for various operations". The 512 MB RAM floor is our estimate; restic publishes no requirement.