Backups are the work nobody pays attention to until the day everything depends on them. The bad news: many people who believe they have backups do not — because they have never tried one.
The 3-2-1 rule
This is the simplest widely accepted standard:
- 3 copies of the data (the original plus two backups)
- On 2 different media or systems
- With 1 copy physically in another location
The purpose is to stop a single event from destroying every copy at once. Keeping a backup on the same disk as the server means losing both with that disk. Keeping it in the same data centre produces the same outcome for anything that affects the facility.
What are you backing up?
"I backed up the site" is usually incomplete. List it out:
- Web files — application code and user uploads
- Database — a file copy is not enough; you need a consistent dump
- Configuration — web server, PHP, cron jobs, firewall rules
- Email — mailboxes are a separate data set
- SSL certificates and keys
- Secrets on the server — API keys, environment variables
Backing up configuration is what turns disaster recovery from days into hours.
How often?
The answer depends on one question: how many hours of data can you afford to lose?
- For a corporate site taking a few enquiries a day, a daily backup is fine.
- For an active e-commerce site, a daily backup means up to 24 hours of lost orders in the worst case. You need hourly database backups.
- For rarely updated content like a blog, weekly may be reasonable.
Decide the retention too. A common pattern: 7 daily, 4 weekly, 12 monthly copies.
Automation
A backup taken by hand is a backup not taken. Automate it with a scheduled job.
A simple approach — dump the database and copy files to a remote server:
bash#!/bin/bash
set -euo pipefail
DATE=$(date +%F)
DEST=/var/backups/$DATE
mkdir -p "$DEST"
mysqldump --single-transaction --routines --triggers \
-u backup -p"$DB_PASSWORD" database | gzip > "$DEST/db.sql.gz"
tar czf "$DEST/files.tar.gz" /var/www/yoursite
rsync -az "$DEST/" backup@REMOTE-SERVER:/backups/$DATE/
find /var/backups -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +For more serious needs use restic or BorgBackup. Both take incremental backups (sending only what changed), deduplicate, and handle encryption for you:
bashrestic -r sftp:backup@REMOTE-SERVER:/backups init
restic -r sftp:backup@REMOTE-SERVER:/backups backup /var/www /etc
restic -r sftp:backup@REMOTE-SERVER:/backups forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --pruneEncryption
If your backups leave the server, they should be encrypted. A backup file is a copy of the entire server: the database, user records, passwords sitting in configuration.
Do not store the encryption key where the backups live. Losing the key makes the backup useless too — put key management into a written process.
The step most people skip: testing the restore
This is the most important section of this article.
Taking a backup is half the job; proving you can restore it is the other half. The familiar scenario: the backup job appears to have run cleanly for months, and at the moment of disaster the files turn out to be empty or corrupt.
Once a month, do this:
- Pick a backup at random (not the newest one).
- Restore it to an empty test server or a local virtual machine.
- Start the application and confirm the data is intact.
- Write down how long the restore took.
That fourth item matters: in a real outage, "we have backups" is not the answer you need — "how long until we are back up" is.
Monitoring
Backup jobs failing silently is common. Watch:
- The job's exit code — a failure should notify someone
- The size of the backup file — a sudden drop is the first sign of a broken backup
- The date of the last successful backup
If you would like to review your backup setup together, get in touch.
