Disclosure: we may earn a commission or referral reward from CloudCone, Contabo, DigitalOcean (account credit, not cash), Hostwinds, InterServer, RackNerd, VPSDime and Vultr if you sign up through our links. It does not change the price you pay. Every other provider pays us nothing. Prices in this guide are as of the date shown and may have changed; see the comparison pages for the latest checked prices.

Guides · BLOG

How to set up automated backups on any VPS in 2026

Some prices quoted in this guide are out of date. It is being rebuilt on our price index; for current prices use the comparison pages, which show when each price was checked.

Every VPS provider offers a backup add-on at ~20% of your plan price. Those backups live on the same provider — meaning if your provider has an outage or your account gets disabled, the backups are gone too. This guide walks through a real backup setup: restic + Backblaze B2. Encrypted, deduplicated, off-server, and costs under $1/month for typical workloads.

Why not just use the provider's backup add-on?

Provider-managed backups (Hetzner Backup, DO Snapshots, Vultr Backup) are convenient but:

  • Same provider. If your account is disabled, backups go with it.
  • Same region (usually). A datacenter fire takes both.
  • Limited retention (7-14 days typically).
  • Whole-VM snapshots, not file-level. Restoring a single file is awkward.
  • 20% of plan cost. For a $50 plan, $10/mo — more than off-provider alternatives.

The correct approach: use provider backups as first-line convenience for quick rollbacks, plus off-provider backups for real disaster recovery.

The stack

  • restic — encrypted, deduplicated backup tool. Free and open source.
  • Backblaze B2 — cheap S3-compatible object storage. $6 per TB per month, first 10 GB free.
  • cron — schedule the backup.

Total cost for a small VPS backup (10-50 GB): ~$0-1/mo.

Step 1: Install restic

On Debian/Ubuntu:

```bash

apt update

apt install restic

```

On CentOS/Rocky:

```bash

yum install epel-release

yum install restic

```

Or download the latest binary from github.com/restic/restic/releases.

Step 2: Create a Backblaze B2 bucket

  • Sign up at backblaze.com.
  • Create an application key with read/write access.
  • Create a private bucket for backups (e.g., myvps-backups).
  • Note down: your key ID, application key, and bucket name.

Step 3: Initialise the restic repository

```bash

export B2_ACCOUNT_ID="your-key-id"

export B2_ACCOUNT_KEY="your-application-key"

export RESTIC_REPOSITORY="b2:myvps-backups"

export RESTIC_PASSWORD="a-strong-passphrase-you-will-not-forget"

restic init

```

Write down the passphrase in your password manager. Without it, your backups are unreadable.

Step 4: Run your first backup

```bash

restic backup /var/www /etc/nginx /home

```

restic scans, deduplicates, encrypts, and uploads. First backup takes minutes to hours depending on size.

Verify:

```bash

restic snapshots

restic ls latest

```

Step 5: Automate with cron

Create /etc/backup-env:

```bash

B2_ACCOUNT_ID=your-key-id

B2_ACCOUNT_KEY=your-application-key

RESTIC_REPOSITORY=b2:myvps-backups

RESTIC_PASSWORD=your-passphrase

```

chmod 600 /etc/backup-env — nobody but root should read it.

Create /usr/local/bin/backup-vps:

```bash

#!/bin/bash

set -euo pipefail

source /etc/backup-env

export B2_ACCOUNT_ID B2_ACCOUNT_KEY RESTIC_REPOSITORY RESTIC_PASSWORD

Dump databases to /tmp before backing them up

sudo -u postgres pg_dumpall | gzip > /tmp/postgres-backup.sql.gz

Or MySQL

mysqldump --all-databases | gzip > /tmp/mysql-backup.sql.gz

Backup: files, config, database dumps

restic backup \

/var/www \

/etc/nginx \

/etc/systemd/system \

/home \

/tmp/postgres-backup.sql.gz

Clean up dumps

rm -f /tmp/postgres-backup.sql.gz

Prune old snapshots (keep last 7 daily, 4 weekly, 12 monthly)

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

```

chmod +x /usr/local/bin/backup-vps.

Add cron entry:

```bash

crontab -e

Run daily at 3 AM

0 3 * /usr/local/bin/backup-vps >> /var/log/backup.log 2>&1

```

Step 6: Test restore

Never trust an untested backup. Immediately do a restore drill:

```bash

List available snapshots

restic snapshots

Restore the latest snapshot to a temp directory

mkdir -p /tmp/restore-test

restic restore latest --target /tmp/restore-test

Verify files are there

ls /tmp/restore-test/var/www/

Clean up

rm -rf /tmp/restore-test

```

Repeat this quarterly. A backup you can't restore is not a backup.

Step 7: Monitor the cron

The last thing you want is a backup that silently stopped working three weeks ago.

Simplest: send yourself an email if the cron fails. Add to the backup script:

```bash

At end of script

if [ $? -ne 0 ]; then

mail -s "VPS backup FAILED on $(hostname)" [email protected] < /var/log/backup.log

fi

```

Requires mailutils and a working SMTP setup (Postfix relay or Sendgrid/Mailgun SMTP).

Better: use a monitoring service that pings if the cron fails to run:

  • Healthchecks.io — free tier, ping URL from your cron. If no ping in the expected window, alerts you.

Add to your script:

```bash

curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/YOUR-UUID

```

Cost math

For a 20 GB working set + database:

  • Initial upload: ~20 GB.
  • Daily incremental: ~100 MB new/changed data.
  • With deduplication, 30 days retained: ~25 GB stored on B2.
  • Cost: 25 GB × $0.006/GB-month = $0.15/mo.

Even for a 200 GB working set with heavy churn:

  • ~150 GB stored.
  • Cost: $0.90/mo.

What you gain vs the provider's backup add-on

  • Off-provider. Survives account disable, provider outage, whole-region outage.
  • Encrypted. No provider staff can read your data.
  • Deduplicated. Same data isn't stored twice.
  • File-level restore. Restore one file, not just a whole VM.
  • Configurable retention. 12 months of monthly backups by default.
  • Cheaper. Under $1/mo for typical VPS.

Common gotchas

"Bucket already exists" on Backblaze. Bucket names are globally unique. Use a prefix like myuser-myvps-backups.

Backup takes hours. First upload is slow. Subsequent runs are fast (deduplication + incremental).

Passphrase lost. Backups are unrecoverable. Store in your password manager AND in a printed sealed envelope somewhere safe.

Cron doesn't run. Cron mails errors to root. Check /var/log/cron or journalctl -u cron.

Database dump is inconsistent. For Postgres, use pg_dump (consistent) not filesystem copy. For MySQL, use mysqldump --single-transaction on InnoDB.

Related guides