18 KiB
created, id, keywords, links, modified, summary, tags, title
| created | id | keywords | links | modified | summary | tags | title | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-04-16T04:06:58+00:00 | 8fc5d55f-1466-4414-860f-ae84c1f39ebf |
|
2026-04-16T04:06:58+00:00 | Comprehensive reference for restic 0.18.1 — a fast, secure, efficient backup program written in Go. Covers installation, all storage backends, backup/restore/forget workflows, encryption, deduplication, repository internals, environment variables, and troubleshooting. |
|
Restic Backup Reference |
id: restic title: Restic Backup Reference created: 2025-07-10 modified: 2025-07-10 tags:
- backup
- restic
- encryption
- deduplication
- CLI
- reference links:
- reference/docker-compose.md
- reference/crowdsec.md
Restic — Backups Done Right
Version: 0.18.1 License: BSD 2-Clause Language: Go URL: https://restic.net/ Docs: https://restic.readthedocs.io/en/stable/
Overview
Restic is a fast, secure, efficient backup program. It supports Linux, macOS, Windows, FreeBSD, OpenBSD. It is a single binary with no server component required. Key features:
- Deduplication — Content-defined chunking with Rabin Fingerprints; only changed data is transferred/stored
- Encryption — AES-256-CTR + Poly1305-AES MAC on all data; scrypt key derivation from user password
- Compression — zstandard compression (repository format v2, default since 0.14)
- Verification — SHA-256 hashing of all blobs;
restic checkvalidates integrity - Multiple backends — Local, SFTP, REST, S3, Azure Blob, Google Cloud Storage, Backblaze B2, OpenStack Swift, rclone
- No server required — Single static binary; no daemon
Installation
Package Managers
| Platform | Command |
|---|---|
| Debian/Ubuntu | apt-get install restic |
| Fedora/RHEL/CentOS | dnf install restic (or via EPEL for RHEL 8/9) |
| Arch Linux | pacman -S restic |
| Alpine | apk add restic |
| macOS (Homebrew) | brew install restic |
| macOS (MacPorts) | port install restic |
| macOS (pkgx) | pkgx install restic |
| Nix/NixOS | nix-env --install restic |
| FreeBSD | pkg install restic |
| OpenBSD | pkg_add restic |
| openSUSE | zypper install restic |
| Windows (winget) | winget install --exact --id restic.restic --scope Machine |
| Windows (Scoop) | scoop install restic |
| Solus | eopkg install restic |
| Gentoo | emerge restic |
Official Binaries
Download from https://github.com/restic/restic/releases — reproducible builds with GPG verification (key 0x91A6868BD3F7A907). Update in-place with restic self-update.
Docker
docker pull restic/restic
# or from GHCR:
docker pull ghcr.io/restic/restic
Note: Set a static hostname with
--hostnamewhen running in Docker.
From Source
Requires Go 1.23+:
git clone https://github.com/restic/restic && cd restic && go run build.go
Produces a statically linked binary. Cross-compilation supported.
Autocompletion
restic generate --bash-completion /path/to/completion
restic generate --zsh-completion /path/to/completion
restic generate --fish-completion /path/to/completion
restic generate --man /path/to/manpages
restic generate --powershell-completion /path/to/completion
Quickstart
# Set environment variables
export RESTIC_REPOSITORY=/srv/restic-repo
export RESTIC_PASSWORD=some-strong-password
# Initialize repository (first time only)
restic init
# Create backup
restic backup ~/work
# List snapshots
restic snapshots
# Restore
restic restore --target /tmp/restore-work your-snapshot-ID
# Verify integrity
restic check
restic check --read-data # full data verification
Preparing a New Repository
Repository Versions
| Version | Min restic | Major Features |
|---|---|---|
1 |
Any | Original format |
2 |
0.14.0+ | Compression support (current default) |
Specify with restic init --repository-version 2 or --repository-version latest.
Password Management Options
- Environment variable:
RESTIC_PASSWORD - Password file:
--password-fileorRESTIC_PASSWORD_FILE - Password command:
--password-commandorRESTIC_PASSWORD_COMMAND - Interactive prompt (default)
Backend Types
Local
restic init --repo /srv/restic-repo
SFTP
restic -r sftp:user@host:/srv/restic-repo init
# With port and IPv6:
restic -r sftp://user@[::1]:2222//srv/restic-repo init
# Use SSH config host aliases:
restic -r sftp:my-backup-host:/srv/restic-repo init
# Custom SFTP command:
restic -r sftp:foo:/repo -o sftp.command="foobar"
SSH keepalive recommended:
ServerAliveInterval 60
ServerAliveCountMax 240
REST Server
restic -r rest:http://host:8000/ init
restic -r rest:https://user:pass@host:8000/ init
restic -r rest:http+unix:///tmp/rest.socket:/repo init
TLS cert override: --cacert. Env vars: RESTIC_REST_USERNAME, RESTIC_REST_PASSWORD.
Amazon S3
export AWS_ACCESS_KEY_ID=<KEY>
export AWS_SECRET_ACCESS_KEY=<SECRET>
export AWS_SESSION_TOKEN=<TOKEN> # for temporary credentials
restic -r s3:s3.us-east-1.amazonaws.com/bucket_name init
Note: restic uses path-style URLs, not virtual-hosted style.
S3-Compatible (Minio, Wasabi, Alibaba OSS, etc.)
export AWS_ACCESS_KEY_ID=<KEY>
export AWS_SECRET_ACCESS_KEY=<SECRET>
restic -r s3:https://server:port/bucket_name init
# Options:
# -o s3.region="us-east-1"
# -o s3.bucket-lookup=auto|dns|path
# -o s3.list-objects-v1=true # for old Ceph
Backblaze B2
# Recommended: use S3-compatible API (see B2 docs for S3 keys)
# Legacy B2 backend (less reliable error handling):
export B2_ACCOUNT_ID=<ID>
export B2_ACCOUNT_KEY=<KEY>
restic -r b2:bucketname:path/to/repo init
Microsoft Azure Blob Storage
export AZURE_ACCOUNT_NAME=<NAME>
export AZURE_ACCOUNT_KEY=<KEY> # or AZURE_ACCOUNT_SAS=<SAS>
# Or use: az login (needs Storage Blob Data Contributor role)
restic -r azure:container:/ init
# Options: -o azure.connections=10, -o azure.access-tier=Hot|Cool|Cold
Google Cloud Storage
export GOOGLE_PROJECT_ID=<ID>
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json
restic -r gs:bucket:/ init
# Options: -o gs.connections=10, -o gs.region=us
OpenStack Swift
# Keystone v1/v2/v3 auth via environment variables
# (ST_AUTH, ST_USER, ST_KEY for v1; OS_AUTH_URL, OS_USERNAME, etc. for v2/v3)
restic -r swift:container_name:/path init
rclone (any supported remote)
restic -r rclone:remote_name:path init
# Options: -o rclone.program, -o rclone.args, -o rclone.timeout
# Remote rclone via SSH:
restic -o rclone.program="ssh user@remotehost rclone" -r rclone:b2:foo/bar
Group-Accessible Repositories
Since v0.14, local and SFTP repos can be shared with a group:
# Read-only: chmod -R g+r /srv/restic-repo
# Read-write: requires root to set setgid
# find /srv/restic-repo -type d -exec chmod g+s '{}' \;
# chmod -R g+rw /srv/restic-repo
Backing Up
Basic Backup
restic -r /repo backup ~/work
restic -r /repo backup ~/work.txt # individual files
File Change Detection
On Unix, a file is considered unchanged if all of these match a previous backup:
- Modification timestamp (mtime)
- Metadata change timestamp (ctime)
- File size
- Inode number
Options to modify:
--force— rescan all files--ignore-ctime— only require mtime match--ignore-inode— allow inode and ctime to differ (for FUSE filesystems)
Parent snapshot selection defaults to --group-by host,paths.
Skip Unchanged Snapshots
restic backup ~/work --skip-if-unchanged
Dry Run
restic backup ~/work --dry-run -vv
Excluding Files
Options:
--exclude "pattern"/--iexclude "pattern"(case-insensitive)--exclude-file file/--iexclude-file file--exclude-caches— skip folders with CACHEDIR.TAG--exclude-if-present foo— skip folders containing filefoo--exclude-larger-than 1M— skip files over size--exclude-cloud-files— skip cloud-only files (Windows)
Pattern syntax uses Go's filepath.Match:
foomatches/dir/fooand/dir/foo/filebut not/dir/foobar- Leading
/anchors to root **matches across directories!patterncancels a previous match (like gitignore)- Environment variables expanded with
$VAR --one-file-systemprevents crossing mount boundaries
Including Files
restic backup --files-from /path/to/patterns
restic backup --files-from-verbatim /path/to/list # no glob expansion
restic backup --files-from-raw /path/to/list # NUL-delimited
Comparing Snapshots
restic diff snapshot1 snapshot2
restic diff snapshot1:/subfolder snapshot2:/subfolder
restic diff snapshot1 snapshot2 --metadata
Status codes: + added, - removed, T type changed, M content changed, U metadata changed, ? bitrot detected.
Backing Up from Commands/Stdin
# Recommended: from command (detects failures)
restic backup --stdin-filename db.sql --stdin-from-command -- mysqldump --host example mydb
# Stdin pipe (masks command failures — use with set -o pipefail)
mysqldump mydb | restic backup --stdin --stdin-filename db.sql
Tags
restic backup --tag projectX --tag foo ~/work
Tags used for snapshot selection with forget and tag commands.
Windows VSS
restic backup C:\ --use-fs-snapshot
# Options:
# -o vss.timeout=2m30s
# -o vss.exclude-all-mount-points=true
# -o vss.exclude-volumes="d:;c:\mnt"
Exit Status Codes
0— success (snapshot created with all files)1— fatal error (no snapshot created)3— some source files unreadable (incomplete snapshot created)
Scheduling Backups
Restic has no built-in scheduler. Options:
- Linux/BSD: systemd timers, cron
- Windows: Task Scheduler
- Wrapper tools: resticprofile
Always detect already-running instances before starting a backup.
Environment Variables
| Variable | Purpose |
|---|---|
RESTIC_REPOSITORY |
Repository location |
RESTIC_REPOSITORY_FILE |
File containing repository location |
RESTIC_PASSWORD |
Repository password |
RESTIC_PASSWORD_FILE |
File containing password |
RESTIC_PASSWORD_COMMAND |
Command to print password |
RESTIC_CACHE_DIR |
Cache directory location |
RESTIC_COMPRESSION |
Compression mode (v2 only) |
RESTIC_HOST |
Set/override hostname for snapshots |
RESTIC_PACK_SIZE |
Target pack file size |
RESTIC_READ_CONCURRENCY |
File read concurrency |
RESTIC_PROGRESS_FPS |
Progress bar refresh rate |
RESTIC_CACERT |
TLS CA certificate(s) |
RESTIC_TLS_CLIENT_CERT |
TLS client certificate |
RESTIC_KEY_HINT |
Key ID to try first |
AWS_ACCESS_KEY_ID |
S3 access key |
AWS_SECRET_ACCESS_KEY |
S3 secret key |
AWS_SESSION_TOKEN |
S3 temporary session token |
AWS_DEFAULT_REGION |
S3 default region |
AWS_PROFILE |
AWS credentials profile |
AZURE_ACCOUNT_NAME |
Azure account name |
AZURE_ACCOUNT_KEY |
Azure account key |
AZURE_ACCOUNT_SAS |
Azure SAS token |
GOOGLE_PROJECT_ID |
GCP project ID |
GOOGLE_APPLICATION_CREDENTIALS |
GCP service account JSON key |
B2_ACCOUNT_ID |
Backblaze B2 account ID |
B2_ACCOUNT_KEY |
Backblaze B2 application key |
RESTIC_REST_USERNAME |
REST server username |
RESTIC_REST_PASSWORD |
REST server password |
Working with Repositories
Listing Snapshots
restic snapshots
restic snapshots --group-by host,paths # default
restic snapshots --host myhost --tag foo
Listing Files in a Snapshot
restic ls latest
restic ls snapshot-id /path/within/snapshot
Restoring
restic restore --target /tmp/restore snapshot-id
restic restore --target /tmp/restore --include "*.txt" snapshot-id
restic restore --target /tmp/restore --exclude "*.c" snapshot-id
# Mount as filesystem:
restic mount /mnt/restic
# Print to stdout:
restic dump snapshot-id path/to/file
Copying Snapshots Between Repositories
restic copy --repo-copy /other-repo snapshot-id
Removing Files from Snapshots
restic forget --keep-last 5 snapshot-id # remove from repo
restic rewrite --exclude "pattern" snapshot-id # create new snapshot without matching files
Modifying Snapshot Metadata
restic tag --tag newtag snapshot-id
restic tag --remove tagname snapshot-id
Checking Integrity
restic check # check metadata
restic check --read-data # verify all data
restic check --check-unused # find unused blobs
Removing Backup Snapshots
Manual Removal
restic forget snapshot-id
restic prune # cleanup unreferenced data
Policy-Based Removal
restic forget --keep-last 7 --keep-daily 14 --keep-weekly 8 --keep-monthly 12 --keep-yearly 5 --prune
Policy options:
| Option | Description |
|---|---|
--keep-last N |
Keep last N snapshots |
--keep-hourly N |
Keep most recent snapshot for each of last N hours with snapshots |
--keep-daily N |
Keep most recent snapshot for each of last N days with snapshots |
--keep-weekly N |
Keep most recent snapshot for each of last N weeks |
--keep-monthly N |
Keep most recent snapshot for each of last N months |
--keep-yearly N |
Keep most recent snapshot for each of last N years |
--keep-tag TAG |
Keep all snapshots with specified tag(s) |
--keep-within DURATION |
Keep snapshots within duration of latest (e.g., 2y5m7d3h) |
--keep-within-{hourly,daily,weekly,monthly,yearly} DURATION |
Duration-based variants |
Options work on natural time boundaries (weeks are Mon–Sun, hours are :00–:59). Results are ORed — a snapshot only needs to match one option to be kept. Grouped by --group-by host,paths by default.
All policies support --dry-run. --unsafe-allow-remove-all allows removing all snapshots for a specific filter (v0.17+).
Append-Only Mode Security
When using append-only repositories (e.g., via rest-server), use --keep-within policies. Calendar-based policies (--keep-daily, etc.) can be gamed by attackers injecting fake snapshots. --keep-within keeps both legitimate and attacker snapshots, allowing detection.
Customizing Pruning
restic prune # default: 5% max unused
restic prune --max-unused 200M # absolute size limit
restic prune --max-unused 10% # relative to repo size
restic prune --max-unused unlimited # never repack (fast, but wastes space)
restic prune --max-repack-size 10G # limit total repack size
restic prune --repack-cacheable-only # only repack cached metadata (fast)
restic prune --repack-small # repack packs below 80% target size
restic prune --repack-smaller-than 5M # repack packs below this size
Recovering from "No Free Space"
# Step 1: forget some snapshots
restic forget --keep-last 1
# Step 2: minimal prune
restic prune --max-repack-size 0
# Step 3: if still stuck (last resort):
restic prune --unsafe-recover-no-free-space <ID>
Tuning Backup Parameters
| Parameter | Option | Default |
|---|---|---|
| Progress estimation | --no-scan / RESTIC_PROGRESS_FPS |
Enabled |
| Backend connections | -o backend.connections=N |
5 |
| CPU usage | GOMAXPROCS=N env var |
All cores |
| Compression | --compression auto|max|off |
auto |
| Data verification | --insecure-no-verify (dangerous) |
Enabled |
| File read concurrency | --read-concurrency N or RESTIC_READ_CONCURRENCY |
2 |
| Pack size | --pack-size N or RESTIC_PACK_SIZE |
8 MiB |
| Feature flags | -o feature.<name>=true |
— |
Encryption
- Algorithm: AES-256-CTR + Poly1305-AES MAC
- KDF: scrypt (N=65536, r=8, p=1)
- Key management: Multiple keys supported; password change doesn't require re-encryption
- All data encrypted except informational metadata in key files
- Cache is also encrypted
Key Management
restic key list
restic key add
restic key remove <ID>
restic key passwd
restic key set <ID> # set default key hint
Repository Design
Repository Layout
restic-repo/
├── config # encrypted JSON (version, ID, chunker params)
├── data/ # pack files (two-char prefix dirs)
│ ├── 21/
│ ├── 32/
│ └── ...
├── index/ # index files mapping blobs to packs
├── keys/ # encrypted key files (scrypt-derived)
├── locks/ # lock files for concurrent access
├── snapshots/ # snapshot metadata
└── tmp/ # temporary files
Pack Format
Each pack file contains:
EncryptedBlob1 || ... || EncryptedBlobN || EncryptedHeader || Header_Length
Blob types: 0b00 data, 0b01 tree, 0b10 compressed data, 0b11 compressed tree (v2 only).
Deduplication
Content-defined chunking with Rabin Fingerprints (64-byte sliding window). Blob sizes: 512 KiB to 8 MiB (target 1 MiB average). Only modified blobs stored in subsequent backups — works even with byte insertions/removals at arbitrary positions.
Snapshots
Each backup creates a snapshot — a JSON document recording paths, hostname, username, time, tags, and the root tree hash. Snapshots are immutable once created.
Locking
Two lock types: exclusive (for prune/rewrite) and non-exclusive (for backup/restore). Locks older than 30 minutes are considered stale. Use --retry-lock <duration> to wait for locks.
Scripting
# JSON output
restic snapshots --json
restic backup ~/work --json
# Check if repo is initialized
restic cat config
# Exit codes for scripting
# 0 = success, 1 = fatal error, 3 = partial (some files unreadable)
# 10 = repo locked, 11 = connection error (and others)
Troubleshooting
- Find what's damaged:
restic check - Backup the repository (copy data files)
- Repair index:
restic repair index - Run all backups
- Remove missing data from snapshots:
restic repair snapshots - Check again:
restic check