VPS Backup Strategy: A Complete Guide to Not Losing Your Data

Published on

How to implement a proper backup strategy for your VPS. Covers automated backups, off-site storage, testing, and the 3-2-1 backup rule.

VPS hosting

The question isn't if you'll need a backup. It's when. A proper backup strategy is the difference between a 5-minute recovery and a catastrophic data loss.

The 3-2-1 Rule

RuleMeaningExample
3 copiesKeep three copies of dataOriginal + 2 backups
2 media typesStore on two different mediaVPS disk + object storage
1 off-siteAt least one copy off-siteRemote server or cloud

What to Back Up

DataPriorityFrequency
DatabasesCriticalEvery 6 hours
Application codeHighDaily (or use Git)
Configuration filesHighAfter every change
User uploadsCriticalDaily
SSL certificatesMediumAfter renewal
Cron jobs and scriptsMediumAfter changes

Don't Back Up

  • OS files (reinstall from scratch faster than restoring)
  • Package cache (/var/cache/apt/)
  • Temporary files (/tmp/)
  • Log files (unless needed for compliance)

Automated Backup Script

#!/bin/bash
# /opt/backups/backup.sh

set -e

DATE=$(date +%Y%m%d-%H%M)
BACKUP_DIR="/opt/backups/local"
RETENTION_DAYS=7

mkdir -p "$BACKUP_DIR"

echo "Starting backup: $DATE"

# Database backup
echo "Backing up databases..."
mysqldump --all-databases --single-transaction     > "$BACKUP_DIR/databases-$DATE.sql"

# Web files backup
echo "Backing up web files..."
tar czf "$BACKUP_DIR/www-$DATE.tar.gz"     --exclude='node_modules'     --exclude='.git'     /var/www/

# Configuration backup
echo "Backing up configurations..."
tar czf "$BACKUP_DIR/config-$DATE.tar.gz"     /etc/nginx/     /etc/php/     /etc/mysql/     /etc/letsencrypt/     /etc/crontab

# Remove old backups
echo "Cleaning old backups..."
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.sql" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: $DATE"

Schedule it:

crontab -e
# Run daily at 2 AM
0 2 * * * /opt/backups/backup.sh >> /var/log/backup.log 2>&1

Off-Site Backup with rclone

# Install rclone
sudo apt install rclone
rclone config  # Set up your remote storage

Sync to Cloud Storage

# Sync local backups to cloud
rclone sync /opt/backups/local remote:vps-backups/

# Add to backup script
rclone copy "$BACKUP_DIR/databases-$DATE.sql" remote:vps-backups/
rclone copy "$BACKUP_DIR/www-$DATE.tar.gz" remote:vps-backups/

Supported Destinations

StorageCostIntegration
Backblaze B2$0.005/GB/monthrclone, s3cmd
AWS S3$0.023/GB/monthrclone, aws-cli
Wasabi$0.0069/GB/monthrclone, s3cmd
Google Cloud Storage$0.020/GB/monthrclone
Another VPS (rsync)VPS costrsync

Backup Verification

A backup that doesn't restore is not a backup:

#!/bin/bash
# /opt/backups/verify.sh

# Test database restore to temporary database
mysql -e "CREATE DATABASE backup_test;"
mysql backup_test < /opt/backups/local/databases-latest.sql
TABLES=$(mysql -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='backup_test';")
echo "Restored $TABLES tables"
mysql -e "DROP DATABASE backup_test;"

# Test file archive integrity
tar tzf /opt/backups/local/www-latest.tar.gz > /dev/null
echo "Archive integrity: OK"

Backup Schedule Recommendation

Data TypeFrequencyRetentionLocation
DatabaseEvery 6 hours14 daysLocal + off-site
Web filesDaily7 daysLocal + off-site
ConfigsAfter change30 daysLocal + off-site
Full serverWeekly4 weeksOff-site only

Recovery Time Estimates

ScenarioRecovery FromEstimated Time
Deleted fileFile backup5-10 minutes
Corrupted databaseDatabase dump10-30 minutes
Hacked serverFull backup + clean reinstall1-3 hours
Hardware failureOff-site backup + new VPS2-4 hours

Regular backups on Space-Node's VPS run fast thanks to NVMe SSD storage. Database dumps and file compressions complete quickly, minimizing the performance impact of backup operations.

Ready to deploy?

KVM VPS from EUR 5.50/mo with full root access, NVMe storage, and DDoS protection included.