# Backups (snapshots)

A snapshot is a backup of a [volume](/docs/volumes): all its files as one archive. Take one before a risky change, put volumes on a schedule, and restore, download or delete snapshots in the service's **Volumes** tab.

## Take one

Open the service's **Volumes** tab, choose **Snapshots** on the volume, then **Take a snapshot**. A note ("before the migration") helps you find it later. It shows as *Being taken…* and, a moment later, with its size.

While its files are copied, the service is **frozen**: its processes stand still, requests wait, and everything carries on afterwards. That takes about as long as copying the data: under a second for a small app's files, a few seconds per gigabyte for a database. A service that's asleep is copied as it is, without waking it.

## Why freezing makes a database's snapshot safe

Copying a database's files while it writes to them gives a copy that may not open. With the service frozen, the files are exactly what a power cut would leave behind, and that is something PostgreSQL, MySQL, SQLite, Redis and the like are built to start from: they replay their own log and come up with every committed change. It's the same guarantee a disk snapshot from a cloud provider gives.

## Restore

**Restore** on a snapshot puts its files back into the volume:

1. The service is stopped.
2. The volume is emptied and filled with the snapshot's files, owners and permissions as they were.
3. The service starts again on them.

Everything written since the snapshot is gone, so take a new snapshot first if you might want today's state back. The service is down for as long as the files take to copy.

## On a schedule

Choose **Every hour**, **6 hours**, **12 hours**, **day** or **week** next to *On a schedule*, and how many to keep: older scheduled snapshots are deleted as new ones arrive. A smaller count, or switching the schedule off, applies at once: the older scheduled ones are deleted right away. Snapshots taken by hand are never deleted by the schedule.

If a scheduled snapshot fails (the server is offline, its disk is nearly full), it shows in the list with the reason and is tried again an hour later. To hear about it, add **A scheduled snapshot of a volume failed** to a [notification channel](/docs/notifications).

## How many are kept

Every snapshot is a whole copy of its volume, so they don't pile up. Per volume:

| Taken | Kept |
| --- | --- |
| On the schedule | The newest *n*, as you set it (7 unless you choose otherwise). |
| By hand | The newest 10. When an 11th is taken, the oldest of them is deleted. |
| By a coding agent | 7 days, unless you **Keep** it, and at most the newest 10. |

An agent's snapshot is a safety net for the change it's making, so it goes by itself after a week; it shows *deleted in …* until then. **Keep** makes it stay like one you took by hand (it then counts among those 10). Agents can't keep their own.

Deleted means everywhere: the file on the server and its copy off the server.

## Where snapshots are kept

On the same server as the volume, compressed. That makes them quick to take and to restore, and it protects against what usually goes wrong: a bad migration, a deleted table, an app that corrupted its files.

It does **not** protect against losing the server or its disk. For that there are copies off the server.

- Snapshots use the server's disk. One is never allowed to fill it: a snapshot that would leave less than 1 GB free is given up, and says so.
- Deleting a volume (or its service) deletes its snapshots, and their copies. Download first if you want to keep them.

## Copies off the server

Tick **Keep a copy of every new snapshot off the server** on a volume, and each snapshot (by hand, scheduled or an agent's) is sent to Alf's storage once it's taken. A single snapshot gets one with **Copy off the server**. It shows as *copy off the server* when it has arrived.

```diagram snapshots
A volume, db's data, has its snapshots on the same server's disk: quick to take and to put back. With Keep a copy off the server, each snapshot is also copied to Alf's storage in the background. Restore or Download fetches the copy, onto whichever server the service runs on now. A snapshot covers what usually goes wrong, like a bad migration or a deleted table; a copy off the server covers losing the server.
```

A copy:

- survives the server: if the server is lost, or you move the service to another one, **Restore** fetches the copy onto the service's current server and restores from it;
- is what **Download** hands you, without loading the server;
- is deleted with its snapshot (also when it's one more than a volume keeps), and with the volume;
- counts as storage: **Billing → Usage** lists every copy, what it belongs to and its size, and what was held over the month.

A copy goes up in the background after the snapshot; the service isn't paused for it. If it fails (the connection dropped, say), the snapshot itself is fine and says so: use **Copy off the server** to try again.

## Using a downloaded snapshot

The archive holds the volume's files as the container saw them. Unpack it into an empty directory or volume and start the same image on it:

```bash
mkdir pgdata && tar -xzf db-data-2026-10-11-09-00.tar.gz -C pgdata
docker run -v "$PWD/pgdata:/var/lib/postgresql/data" postgres:17
```

## Good to know

- One snapshot or restore of a volume at a time.
- A snapshot without a copy belongs to its server: if the service later moves to another server, it can still be downloaded, but not restored there. One with a copy off the server can.
- [Previews](/docs/previews) start with empty volumes and no snapshots. [Environments](/docs/previews#environments) start empty too, with the original's backup schedules.
- [Coding agents](/docs/agent-tools) can take a snapshot before they change a database (`create_snapshot`), and restore one (`restore_snapshot`).
- Servers need a current smartalfred-server; the dashboard says so when one is too old.
