The 3-2-1 backup rule existed before cloud hosting and still applies: three copies of data, on two different media, with at least one copy offsite. For VPS workloads that translates to a pragmatic three-layer strategy.

Why provider snapshots alone aren't backups

Snapshots are a convenience layer, not a disaster recovery strategy. Failure modes they don't cover:

  • Provider-wide outage or data loss (OVH Strasbourg 2021, some Linode / Vultr incidents)
  • Account compromise — attacker deletes instances AND snapshots
  • Billing issue causing account suspension
  • Single-region snapshot lost when the region goes down
  • Logical corruption not caught before snapshot cycles out

The three-layer model

LayerToolFrequencyRetentionPurpose
1. Provider snapshotNative (DO, Linode, Vultr)Daily7 daysFast rollback
2. File-level backupBorg, Restic, DuplicityHourly-daily30-90 daysGranular restore, encryption
3. Offsite at different providerrsync + cron, rclone, B2/S3/R2Daily-weekly90+ daysProvider-independent disaster recovery

Storage destinations compared

DestinationPrice/TB/monthEgress costNotes
Backblaze B2$6Free up to 3x storageIndustry-standard for backups, S3-compatible API
Cloudflare R2$15$0 egressNo egress fees, S3-compatible
AWS S3 Standard$23$0.09/GBExpensive for backup; use S3 Glacier Deep Archive instead
S3 Glacier Deep Archive$1$0.09/GBVery cheap storage; 12-hour retrieval, use for long-term only
Wasabi$7Free (with conditions)S3-compatible, no egress fees but 90-day minimum retention billing
Hetzner Storage Box~$4FreeCheapest option; SFTP / Borg / rsync
rsync.net~$13FreeDedicated ZFS-backed backup host, daily snapshots

Borg vs Restic vs Duplicity

All three handle encrypted, deduplicated backups. Key differences:

  • BorgBackup: Deduplication is legendary; efficient for repeated backups of large file trees. Self-hosted repository required.
  • Restic: Similar strengths, but natively supports cloud object storage (S3, B2, Azure, GCS) as backends.
  • Duplicity: Older, uses GPG for encryption, less efficient dedup but widely supported.

For most operators in 2026: Restic is the sensible default — one binary, works with any S3-compatible storage, good performance, actively maintained.

A minimal working setup

  1. Install Restic on the VPS.
  2. Initialize a repository on Backblaze B2 (or Hetzner Storage Box, or Cloudflare R2).
  3. Script a daily backup via cron: snapshot /etc, /var/www, /home, database dumps, and any application state directories.
  4. Dump MySQL/Postgres to a file before backing up (running DB files directly without a dump can produce corrupt backups).
  5. Run restic check monthly to verify integrity.
  6. Run a trial restore to a scratch VM quarterly.

Database-specific concerns

  • MySQL: mysqldump --single-transaction --routines --triggers
  • Postgres: pg_dump in custom format, or pg_basebackup for binary-level
  • Do not back up the raw data directory on a live database — it's a recipe for silent corruption.
  • For larger databases, consider point-in-time recovery via WAL archiving (Postgres) or binary logs (MySQL).

Restore testing

Untested backups are a theology, not a strategy. Quarterly drills:

  1. Spin up a scratch VPS (smallest plan, $4-6).
  2. Restore from your backup.
  3. Verify application boots, database queries return expected rows, key URLs load.
  4. Document the time it took — RTO (recovery time objective) should match your business tolerance.
  5. Destroy the scratch VPS.

FAQ

How often should I back up? Depends on RPO (recovery point objective — how much data loss is tolerable). Personal blog: daily. E-commerce: hourly or continuous WAL archiving. Internal tool: daily.

How much does a sensible backup setup cost? For a typical 40 GB workload: ~$2-4/month storage + 30 minutes/month of ops time. Tiny relative to the cost of data loss.

Is automated cloud sync enough (Dropbox, Google Drive)? For file backups yes. For databases — no, unless you dump first. Cloud sync tools can't guarantee consistent state of a live DB.