Backups (snapshots)

A snapshot is a backup of a volume: 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.

How many are kept

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

TakenKept
On the scheduleThe newest *n*, as you set it (7 unless you choose otherwise).
By handThe newest 10. When an 11th is taken, the oldest of them is deleted.
By a coding agent7 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.

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.

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:

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:

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