> ## Documentation Index
> Fetch the complete documentation index at: https://help.freakhosting.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Back Up Files with rsync to a Remote Server

> Back up files with rsync to a remote server over SSH: rsync -aAXH --delete /var/www/ backup@host:/backups/www/, with a dry run first, cron and daily snapshots.

To back up files with rsync to a remote server, run `rsync -aAXH --delete /var/www/ backup@198.51.100.20:/backups/www/`. rsync connects over SSH, copies only files that changed and keeps permissions, ACLs and hard links. Test first with `--dry-run`, use an SSH key so it runs unattended, and schedule it with cron.

| Difficulty | Time | Works on | Needs |
| - | - | - | - |
| Intermediate | 20 minutes | Any Linux distribution with rsync and SSH | sudo, a second server or storage box reachable over SSH |

## Before you start

* You need two machines: the **source** (your server) and the **backup host**, for example a second VPS or your own Linux machine. Both need `rsync` installed.
* Commands use `sudo`. Root users can leave it out.
* rsync is often installed already. If not:

> [tab] Ubuntu / Debian
>
> ```bash theme={null}
> sudo apt update && sudo apt install rsync
> ```

> [tab] AlmaLinux / Rocky / Fedora
>
> ```bash theme={null}
> sudo dnf install rsync
> ```

## What do the rsync backup options mean?

| Option | What it does |
| - | - |
| `-a` | Archive mode: recursive, keeps symlinks, permissions, times, owner and group (same as `-rlptgoD`) |
| `-A` | Keeps ACLs (not included in `-a`) |
| `-X` | Keeps extended attributes, such as SELinux labels (not included in `-a`) |
| `-H` | Keeps hard links (not included in `-a`) |
| `--delete` | Deletes files on the backup that no longer exist on the source |
| `-n`, `--dry-run` | Shows what would happen without changing anything |
| `-e "ssh -p 2222"` | Uses SSH on a custom port |
| `--exclude='cache/'` | Skips matching files or folders |

A trailing slash on the source matters: `/var/www/` copies the **contents** of `www`, while `/var/www` creates a `www` folder inside the destination.

## How to set up an rsync backup over SSH

**1. Create an SSH key on the source server**

Backups run as root, so create the key for root:

```bash theme={null}
sudo ssh-keygen -t ed25519 -f /root/.ssh/backup_ed25519 -N ""
```

**2. Allow the key on the backup host**

```bash theme={null}
sudo ssh-copy-id -i /root/.ssh/backup_ed25519.pub backup@198.51.100.20
```

Then test it: `sudo ssh -i /root/.ssh/backup_ed25519 backup@198.51.100.20 hostname`. See [SSH keys](https://help.freakhosting.com/portals/other/how-to-create-and-use-ssh-keys.md).

**3. Create the folder on the backup host**

```bash theme={null}
ssh backup@198.51.100.20 'mkdir -p /backups/www'
```

**4. Do a dry run**

```bash theme={null}
sudo rsync -aAXHn --delete -i -e "ssh -i /root/.ssh/backup_ed25519" \
  /var/www/ backup@198.51.100.20:/backups/www/
```

`-i` lists each change. Lines starting `*deleting` are files rsync would remove from the backup.

**5. Run the backup**

Remove `n` and `-i`:

```bash theme={null}
sudo rsync -aAXH --delete -e "ssh -i /root/.ssh/backup_ed25519" \
  /var/www/ backup@198.51.100.20:/backups/www/
```

> [!WARNING]
>
> `--delete` removes files from the backup when they disappear from the source. If you delete something by mistake, the next run deletes it from the backup too. Swapping source and destination by mistake deletes your live data. Always do a dry run after changing the command, and keep dated snapshots (below) so one bad run cannot wipe everything.

> [!NOTE]
>
> File owners are only kept when rsync runs as root on the **receiving** side. If you back up as a normal user such as `backup`, the files on the backup host belong to that user. The data is safe, but restore permissions carefully, or use restic, which stores ownership inside its repository.

## How to keep daily snapshots with --link-dest

`--link-dest` makes each day's backup look like a full copy, but unchanged files are hard links to the previous day, so they take no extra space.

```bash theme={null}
#!/bin/bash
# /usr/local/bin/rsync-backup.sh
set -euo pipefail
TODAY=$(date +%F)
YESTERDAY=$(date -d yesterday +%F)
rsync -aAXH --delete -e "ssh -i /root/.ssh/backup_ed25519" \
  --link-dest=../$YESTERDAY \
  /var/www/ backup@198.51.100.20:/backups/www/$TODAY/
```

The `--link-dest` path is relative to the destination folder, so `../2026-11-03` points to the day before.

On the first run, when yesterday's folder does not exist, rsync prints `--link-dest arg does not exist` and makes a full copy. That is expected.

Delete old snapshots on the backup host by name, for example keep the newest 30:

```bash theme={null}
ls -1d /backups/www/20*/ | head -n -30                    # list what would be deleted
ls -1d /backups/www/20*/ | head -n -30 | xargs -r rm -rf  # delete it
```

> [!WARNING]
>
> Run the first line on its own and read the list before you run the second. Don't select old snapshots with `find -mtime`: rsync copies the source folder's date onto each snapshot folder, so a brand-new snapshot can look years old.

## How to run the rsync backup every night

```bash theme={null}
sudo chmod 700 /usr/local/bin/rsync-backup.sh
sudo crontab -e
```

Add:

```bash theme={null}
30 2 * * * /usr/local/bin/rsync-backup.sh >> /var/log/rsync-backup.log 2>&1
```

See [schedule tasks with cron](https://help.freakhosting.com/portals/other/how-to-schedule-tasks-with-cron.md).

## How to restore files from an rsync backup

Swap source and destination, and restore to a temporary folder first:

```bash theme={null}
sudo rsync -aAXH -e "ssh -i /root/.ssh/backup_ed25519" \
  backup@198.51.100.20:/backups/www/2026-11-04/example.com/ /tmp/restore/example.com/
```

Check the files, then copy them into place. Do not use `--delete` when restoring unless you mean to make the live folder identical to the backup.

## How to check it worked

```bash theme={null}
ssh backup@198.51.100.20 'ls /backups/www/ && du -sh /backups/www/*'
```

A second dry run straight after a backup should list nothing to transfer.

## Frequently asked questions

### Is rsync a real backup?

A single rsync mirror is a copy, not a history: mistakes and ransomware copy across on the next run. With dated `--link-dest` snapshots it becomes a simple versioned backup. For encryption and deduplication, use [restic](https://help.freakhosting.com/portals/other/how-to-make-encrypted-backups-with-restic.md).

### Should the server push or the backup host pull?

Pulling (the backup host runs rsync and connects to your server) is safer, because an attacker on your server then has no login to the backup host and cannot delete backups. Pushing is simpler to set up.

### How do I use rsync with a custom SSH port?

Add the port to the SSH command: `-e "ssh -p 2222 -i /root/.ssh/backup_ed25519"`.

### How do I exclude folders?

Add `--exclude='cache/'` for each pattern, or list them in a file and use `--exclude-from=/root/rsync-excludes.txt`.

## Related guides

> [card] [VPS and dedicated server guides](https://help.freakhosting.com/portals/other/vps-and-dedicated-server-guides.md)
>
> Every guide in this section.

> [card] [Back up a Linux server](https://help.freakhosting.com/portals/other/how-to-back-up-a-linux-server.md)
>
> What to back up and which tool to use.

> [card] [Copy files with scp and rsync](https://help.freakhosting.com/portals/other/how-to-copy-files-with-scp-and-rsync.md)
>
> One-off transfers between machines.

> [card] [Encrypted backups with restic](https://help.freakhosting.com/portals/other/how-to-make-encrypted-backups-with-restic.md)
>
> Versioned and encrypted.

> [card] [Create and use SSH keys](https://help.freakhosting.com/portals/other/how-to-create-and-use-ssh-keys.md)
>
> Passwordless logins for scripts.

***

> [!NOTE]
>
> **Checked against the official [rsync manual page](https://download.samba.org/pub/rsync/rsync.1)** on 4 November 2026; rsync options, `--delete`, dry run and `--link-dest` tested locally on Ubuntu 24.04 LTS (rsync 3.2.7). Commands can differ on other distributions or releases.

> [!NOTE]
>
> ### Need Extra Help?
>
> If you encounter any issues, our support team is ready to assist:
>
> * **Live Chat:** Quick assistance via our website.
> * **Support Ticket:** [Open a Ticket](https://freakhosting.com/clientarea/submitticket.php)
> * **Discord:** [Join our Community](https://discord.gg/freakhosting)
> * **Email:** [support@freakhosting.com](mailto:support@freakhosting.com)

> [!TIP]
>
> ### Save on Your Hosting
>
> Ready to upgrade your hosting? Use code **KB20** at checkout for **20% off** your first order!

***

**Last Updated:** November 2026


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.