# Backup: encrypted snapshots with zev backup

> Encrypted, deduplicated backups of folders, servers and Postgres databases with one command. To your Zaryn storage, any S3-compatible bucket, or a disk. Only changes are sent, every restore is checked, and a schedule runs it for you.

Source: https://zaryn.xyz/docs/en/backups

`zev backup` takes snapshots of your folders and databases and keeps them encrypted. It sends only what changed since the last one, and it brings back any version of any file. It works on a laptop, a desktop and a server. The backup can go to your Zaryn storage, to any S3-compatible bucket, or to a disk.

```diagram
type: flow
title: Three commands, then it runs by itself
---
Start | zev backup init zaryn: a bucket and a key on your account, a passphrase you keep | accent | 🔐
~ once
Choose | zev backup add ~/Documents /etc --postgres shop | | 📁
~ once
Schedule | zev backup schedule daily: a snapshot every night at 03:00 | | ⏰
~ every day
Restore | zev backup restore yesterday: any file, any day, checked | | ↩
```

## Start: zev backup init

Sign in once with `zev login`. Then:

```bash
zev backup init zaryn ~/Documents ~/Pictures
zev backup run
zev backup schedule daily
```

`init zaryn` makes an S3 key and a bucket on your account, and asks for a **passphrase**. The backup's key is kept on this computer, so scheduled runs need no passphrase. **Write the passphrase down.** It's the only way to open the backup from another computer, and nobody can recover it for you, Zaryn included.

Somewhere else instead:

```bash
zev backup init s3://s3.example.com/my-bucket/laptop    # any S3: set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
zev backup init /mnt/usb-disk/backups                    # a disk, a NAS share, a mounted folder
```

## What goes in

```bash
zev backup add ~/Projects                  # a folder
zev backup add --exclude node_modules      # a name, anywhere below
zev backup add --exclude "*.iso"           # a pattern
zev backup add --exclude ~/.cache          # one path and everything under it
zev backup add --postgres shop             # a Postgres database (a name or a postgresql:// address)
zev backup status                          # what's in, the schedule, the last run
```

Some folders never hold your data: `/proc`, `/sys`, `/dev`, `/run`, `/tmp`, `/var/tmp` and `/var/cache`. zev always skips them, so on a server you can back up `/` and get a sensible result. Sockets and device files are skipped too.

## How only changes are sent

Each file is cut into pieces by its content, not by position. A piece's name is a hash of what's in it, so a piece that's already stored is never sent again. This works across files, across snapshots and across computers that share a backup.

```diagram
type: flow
title: One byte changed in a 12 MB photo
---
Read | The file is cut where its content says (about 1 MB a piece) | | ✂
~
Name | Each piece gets a keyed BLAKE3 name | | #
~ 11 of 12 already there
Send | Only the changed piece, sealed and packed | accent | ↑
~
Snapshot | A new list of pieces: the whole photo, as it is now | | 📸
```

A file whose size and modification time haven't changed isn't even read again, so a nightly run takes little more than the time it takes to list the folders.

```diagram
type: stats
title: In the end-to-end test
---
17.5 MB | the first snapshot (files and a database) | all of it is new | | accent
< 1 MB | the second snapshot, nothing changed | the list of files and a little of the dump | |
~1 MB | one byte changed in a 12 MB file | one piece, not the file | |
0 B | the same photo backed up from a second computer | already there | |
```

## What Zaryn can see: nothing

Everything is encrypted on your computer before it leaves: file contents, file names, folder layout, sizes, the database dump. What reaches the server is sealed packs of about 16 MB with random-looking names.

- **Sealed.** Each piece is compressed (zstd) when that helps, then sealed with AES-256-GCM.
- **Named by a key.** A piece's name is a BLAKE3 hash keyed with your backup's own key, so the server can't recognise a file by its name.
- **Checked on the way back.** On restore every piece is opened and checked against its name. A changed or swapped piece is refused, never written into your files.
- **Your passphrase opens the key.** The backup's key is stored in the bucket sealed with your passphrase (Argon2id). Without the passphrase, or this computer's copy of the key, the backup can't be opened.

## Restore

`<when>` can be `latest`, `yesterday`, `"3 days ago"`, `12h`, a date `2026-10-27`, a moment `"2026-10-27 14:00"`, or a snapshot's id. zev picks the newest snapshot from that moment or before it.

```bash
zev backup list                                    # every snapshot: when, which computer, how much was new
zev backup files yesterday ~/Documents             # what a snapshot holds
zev backup restore latest --to ~/restored          # everything, into a folder
zev backup restore "3 days ago" ~/Documents/thesis.docx --to /tmp/old
zev backup restore yesterday ~/Pictures --in-place # put it back where it was
```

Restored files come back with their permissions, modification times and links. When you run as root, their owners come back too.

**A Postgres database** is backed up with `pg_dump` in its custom format. The dump is consistent even while the database is in use, and it's left uncompressed so that a database that changed a little shares most of its pieces with yesterday's.

```bash
zev backup restore latest postgres:shop --into-postgres shop      # straight back into Postgres
zev backup restore latest postgres:shop --to /tmp/r               # or as a .dump file for pg_restore
```

## Keep and forget

A new backup keeps **7 daily, 4 weekly and 12 monthly** snapshots for each computer, and always the newest. After each run, the snapshots the policy doesn't keep are forgotten. Space that no remaining snapshot needs is freed.

```bash
zev backup keep --daily 14 --weekly 8 --monthly 24 --yearly 5
zev backup forget --dry-run     # what would go, and how much it would free
zev backup keep off             # keep everything
```

```diagram
type: cards
title: What "daily 7, weekly 4, monthly 12" keeps
---
📸 | The newest | Always, whatever the policy says | accent
📅 | Last 7 days | The last snapshot of each day |
🗓 | Last 4 weeks | The last snapshot of each week |
🗂 | Last 12 months | The last snapshot of each month | good
```

Space is freed carefully. New packs and the new index are written before anything is deleted, so an interrupted forget still leaves a backup that restores. A forget waits while a backup is running on another computer.

## Lock it: zev backup protect

```bash
zev backup protect --days 30     # every object locked: not even this computer can delete it
```

Ransomware that takes over the computer has the backup's S3 key too. With `protect`, every object the backup needs is locked for 30 days and renewed while it's needed, so the key can't delete or overwrite any of it. On Zaryn the bucket's trash is on from `init`, and lowering protection waits 3 days with an email to you. See [Ransomware protection](/docs/en/ransomware-protection).

## On a schedule

```bash
zev backup schedule daily     # every night at 03:00
zev backup schedule 01:30     # every day at 01:30
zev backup schedule hourly    # every hour (and then 24 hourly snapshots are kept too)
zev backup schedule off
zev backup schedule daily --print   # see what would be installed
```

On Linux this is a systemd timer (a user timer, or a system one under `sudo`). On a Mac it's a launchd agent, and on Windows a Task Scheduler task. A run missed while the computer was off happens at the next start. Backups run at low priority, so they don't slow you down.

## A second computer, or a lost one

On the new computer:

```bash
AWS_ACCESS_KEY_ID=ZK... AWS_SECRET_ACCESS_KEY=... zev backup connect s3://s3.zaryn.xyz/zev-backup-1a2b3c4d
zev backup list
zev backup restore latest --from old-laptop --to ~/restored
```

`connect` asks for the passphrase. `zev backup status` on the first computer shows the backup's address, and you can [make a key](/storage#s3) on the Storage page. `latest` means this computer's newest snapshot; `--from <computer>` picks another computer's.

Computers that share a backup share their pieces too. Two laptops with the same photo library store it once.

## Check it

```bash
zev backup check               # every snapshot's pieces are there
zev backup check --read-data   # download everything, open and check each piece
zev backup check --repair      # index packs again from their own lists (after an interrupted run)
```

A backup you have never restored from is a hope, not a backup. Once in a while, restore a folder to `/tmp` and look at it.

## How it's counted

On Zaryn, a backup is ordinary [S3 storage](/docs/en/s3-storage) and counts on your [storage plan](/storage#plans). Only what's stored after deduplication counts. The first snapshot costs about the size of your files, compressed. After that, each snapshot costs only what changed.

Related: [S3-compatible storage](/docs/en/s3-storage), [Storing and sharing files](/docs/en/storing-files), [Verified storage](/docs/en/verified-storage).
