How to back up your VPS with rsync
A VPS can fail in ways you cannot fix: a disk dies, a provider has an incident, an update goes wrong, or you delete the wrong folder. The only protection is a backup stored somewhere else. rsync is the standard tool for the job. It copies files efficiently, sending only what changed, and it works over SSH, so a basic but solid backup system takes about ten minutes to build.
What rsync does
It compares a source and a destination, and copies only the differences. The first run copies everything. Later runs copy only new or changed files, which is fast and light on bandwidth. It preserves permissions, dates and ownership when you ask it to.
The core command
rsync -avz /var/www/ backupuser@backup.example-host.net:/backups/www/
The flags:
-a(archive) keeps permissions, owners, dates and links, and recurses into folders.-vprints what it does.-zcompresses data in transit, useful over slower links.
The source is on the left and the destination on the right. If either contains a colon, it is on another machine reached over SSH.
The trailing slash matters
This is the classic mistake:
rsync -a /var/www/ /backup/www/copies the contents ofwwwinto the backup folder.rsync -a /var/www /backup/www/copies the folder itself, creating/backup/www/www/.
Look at the slash after the source. Always test with a dry run first.
Dry run first
rsync -avn /var/www/ /backup/www/
The -n flag shows what would happen without changing anything. Use it every time you change a command, especially with --delete.
Mirroring versus keeping history
By default, rsync only adds and updates. To make the destination an exact mirror, including removing files you deleted at the source, add --delete:
rsync -a --delete /var/www/ /backup/www/
Be careful. A mirror protects against disk failure, but if you accidentally delete a file or an attacker encrypts your data, the next run copies that damage across. To keep older versions, use dated snapshots.
Snapshots with hard links
--link-dest makes each backup look like a full copy while only storing the changes, by hard-linking unchanged files to the previous snapshot:
today=$(date +%F)
rsync -a --delete --link-dest=/backup/latest /var/www/ /backup/$today/
ln -sfn /backup/$today /backup/latest
Each dated folder appears complete, and takes little extra space. You can restore from any day, and delete the oldest folders when you want to free space. This gives you history without needing special software.
Backing up to another machine
A backup on the same disk as the data does not protect you from a failed disk. Send it elsewhere:
- Set up SSH key login to the backup machine. See How to set up SSH key authentication.
- Use a dedicated account on it, with access only to the backup folder.
- Run rsync over SSH, with
-e "ssh -i /home/alex/.ssh/backup_key"if you use a specific key.
Your backup target can be a second VPS, a home server or a storage service that supports SSH or SFTP. Keep it with a different provider if you can.
Exclude what you do not need
rsync -a --exclude 'node_modules' --exclude '*.log' --exclude 'cache/' /home/alex/ /backup/home/
Leave out caches, temporary files and anything you can rebuild. Smaller backups run faster and cost less.
Databases need a dump first
Copying a database's live files can give you a broken copy. Create a dump, then back up the dump file:
sudo mysqldump --single-transaction --databases appdb > /backup/db/appdb.sql
See How to install and secure MariaDB on Ubuntu or How to set up PostgreSQL on Ubuntu. For Docker data, stop the container or use the database's own dump tool.
Run it automatically
Put the commands in a script, make it executable and schedule it with cron. See How to schedule tasks with cron:
0 3 * * * /home/alex/backup.sh >> /var/log/backup.log 2>&1
Log the output, and check it. A backup that has been failing silently for three months is a common discovery at the worst moment.
Test your restore
A backup is only real once you have restored from it. Every so often:
- Restore a folder to a temporary location.
- Check the files open and are complete.
- For a database, import a dump into a test database.
Restoring is the same command with source and destination reversed. Practise before you need it.
Follow the 3-2-1 idea
Keep three copies, on two kinds of storage, with one stored off site. The 3-2-1 backup rule explains why, and Creating and restoring backups covers the panel tools for game and bot servers.
Quick checklist
| Check | Done? |
|---|---|
| Backs up to another machine | |
| Databases are dumped first | |
| Snapshots or history, not only a mirror | |
| Runs on a schedule | |
| Output is logged and reviewed | |
| Restore tested |
Still stuck? Open a ticket on Discord - run /ticket in any channel, pick a department, and include your Server ID or Invoice ID so we can jump straight in.