# What lands on your server

Every path the install writes, what it is, who can read it, and what uninstalling does to it. Nothing else on the server is touched.

## The file tree {#tree}

```text
/
├── usr/local/bin/
│   └── neverwiped                          the agent (one static binary)
├── etc/
│   ├── neverwiped/
│   │   ├── config.json                     configuration, server key, storage login (0600, root)
│   │   └── repo.key                        repository encryption key, never sent (0600, root)
│   └── systemd/system/
│       └── neverwiped-backup.{service,timer}   schedule (or /etc/cron.d/neverwiped, or root’s crontab)
└── var/
    ├── lib/neverwiped/
    │   ├── bin/restic-0.18.1               restic, fingerprint checked
    │   ├── dumps/                          database dumps during a backup, emptied afterwards
    │   ├── volumes/                        paused copies of Docker volumes during a backup, emptied afterwards
    │   └── paused                          containers paused for that copy, until they resume
    ├── cache/neverwiped/                   restic cache
    └── log/neverwiped.log                  local log, one timestamped line per event
```

| Path | What it is | Leaves the server? |
|---|---|---|
| `/usr/local/bin/neverwiped` | The agent: `install`, `status`, `backup now`, `list`, `restore`, `uninstall` | No |
| `/etc/neverwiped/config.json` | Server id, server key, storage login, backup plan, [limits](#limits) | No |
| `/etc/neverwiped/repo.key` | The key that encrypts your backups | **Never** |
| `/etc/systemd/system/neverwiped-backup.timer` | The schedule (systemd); else `/etc/cron.d/neverwiped`; else root’s crontab (BusyBox) | No |
| `/var/lib/neverwiped/bin/` | restic 0.18.1, and `neverwiped.previous` after an [update](#update) | No |
| `/var/lib/neverwiped/dumps/` | Database dumps, only during a backup | Yes, encrypted, inside the backup |
| `/var/lib/neverwiped/volumes/` | Copies of the Docker volumes taken with their containers paused, only during a backup | Yes, encrypted, inside the backup |
| `/var/lib/neverwiped/paused` | IDs of the containers paused for that copy, only during it (the next backup resumes any left paused) | No |
| `/var/cache/neverwiped/` | restic’s cache | No |
| `/var/log/neverwiped.log` | Local log | No (the platform gets a summary of each run: dates, sizes, status, error text) |

What is backed up, by default: `/etc`, `/var/spool/cron`, `/root` and `/home` if not empty, web files (`/var/www`, `/srv`, web roots declared in nginx, Apache or Caddy), apps in `/opt`, PostgreSQL and MySQL/MariaDB (local or in Docker, as consistent dumps), Docker volumes (live, or copied with their containers paused for a few seconds: [A Docker volume](/docs/getting-started#docker-volume)). Excluded by default: `**/node_modules`, `**/.cache`, `/var/cache`, `/var/lib/docker/overlay2`, `/root/.npm`, `/root/go/pkg`, and restic itself. Optional presets (`logs`, `build`, `trash`, `disk-images`, `archives`) leave out more: see [Size and exclusions](/docs/getting-started#size).

## Bandwidth, CPU and priority {#limits}

A backup reads your files, compresses and encrypts them, and sends what changed to the storage. By default it runs at **low priority** (nice 10 and the idle disk class), so your site comes first, with no limit on upload rate or cores. To keep more for your site:

```sh
neverwiped limits
neverwiped limits --limit-upload 20mbit
neverwiped limits --limit-cpus 1
neverwiped limits --priority normal
neverwiped limits --limit-upload off --limit-cpus off --priority low
```

| Limit | What it does | Values |
|---|---|---|
| `--limit-upload` | Caps what restic sends to the storage (restic’s `--limit-upload`) | `20mbit` (or `20Mbps`), `800kbit`, `2MB`, `500KiB`, `off`. A unit is required: Mbit/s and MB/s differ by 8 |
| `--limit-cpus` | restic uses at most N cores to read, compress and encrypt (`GOMAXPROCS`). A cap on parallel work, not an exact quota | `1` to the number of cores (`nproc`), `off` |
| `--priority` | `low`: restic and the local database export tools run under `nice 10` and `ionice -c 3`. `normal`: like any other process | `low` (default), `normal` |

The same options work with `neverwiped install`, so the first backup is already limited. They are saved in `/etc/neverwiped/config.json`, kept when you run `install` again, and shown by `neverwiped status`. They apply to every backup, scheduled or manual, and to the clean-up of old backups. **Restores and `neverwiped list` are never limited.**

Good to know:

- **The first backup sends everything.** With an upload limit, the install prints how long sending the plan takes at most (less after compression and deduplication). A backup started by the systemd timer is stopped after 12 hours: if the first one needs longer, run `neverwiped limits --limit-upload off`, then `neverwiped backup now`, and set the limit again once it is done. The next backups only send changes.
- **Database exports:** the low priority applies to the export tool (`pg_dumpall`, `mysqldump`), not to the database server’s own work for it. For a database in Docker, the export runs inside the container at the container’s priority.
- **Docker volumes copied paused** are always copied at normal priority, so their containers resume as soon as possible.
- **The disk class** (`ionice -c 3`) only has an effect with a disk scheduler that uses it (BFQ, and mq-deadline on recent kernels); on many virtual disks (`none`) it changes nothing, and the nice level and the limits above are what count.
- **Older agents** had `Nice=10` and `IOSchedulingClass=idle` in `neverwiped-backup.service`. The agent now sets the priority itself; the unit is rewritten at the next backup or `neverwiped limits` change.

## Updating the agent {#update}

```sh
neverwiped update --check     # installed version, pin, what is available
neverwiped update             # installs it, after a confirmation
neverwiped update --rollback  # puts the previous version back (no network needed)
```

An update only installs a **signed release**. NeverWiped signs the list of releases with a key kept offline, and the agent carries the matching public key: the platform that serves the files cannot sign, so a tampered list or binary is refused. The agent also refuses a list that has expired or is older than one it already accepted, checks the SHA-256 and the size of the binary, and runs it once before it replaces the current one, which is kept in `/var/lib/neverwiped/bin/neverwiped.previous`. If any step fails, nothing changes. Your configuration, keys, repository and plan are not touched.

- **Pin** a version (`--pin 0.3.1`), a line that only gets fixes (`--pin 0.3`), or follow the newest (`--pin none`). `--rollback` pins the version it puts back.
- **Automatic update** is off by default. `neverwiped update --auto on` lets the nightly backup install what the pin allows, at most once a day, after the backup; a failed update never fails the backup.
- **A withdrawn release** is never installed, and a server running one moves back to the newest good release of its line.
- **Check a binary yourself**: `https://neverwiped.com/downloads/releases/releases.json` lists the size and SHA-256 of every release, and `sha256sum /usr/local/bin/neverwiped` must print one of them.

All options: [command reference](/docs/commands#cmd-update).

## Uninstall {#uninstall}

```sh
neverwiped uninstall --yes
```

In order, it:

1. **refuses while a backup, restore or check is running** (wait for it, then run it again), and resumes any Docker container that a killed run left paused. If one cannot be resumed, it stops and removes nothing;
2. removes the schedule (systemd timer or cron entry);
3. tells the platform: the server shows as “agent uninstalled” and its key is revoked. The account owner gets an e-mail;
4. deletes `/var/lib/neverwiped` (state, restic, the previous agent kept for `update --rollback`), `/var/cache/neverwiped`, `/etc/neverwiped` and `/usr/local/bin/neverwiped`, and prints each path it removed or kept. If a path cannot be removed, it says which one, keeps the binary so you can run it again, and exits with an error.

The log `/var/log/neverwiped.log` is kept; `--remove-log` deletes it too. Nothing else on the server is touched.

### Your backups: kept or deleted, as you choose

| You want | Command | What happens to the backups |
|---|---|---|
| Keep them (default) | `neverwiped uninstall --yes` or `--keep-backups` | They stay on the storage and can be restored with your recovery key (`neverwiped recover` on a new machine). They still count in your storage, and uninstalling does not cancel your subscription. |
| Delete them | `neverwiped uninstall --yes --delete-backups` | The account owner gets an e-mail with a link to the server page in the dashboard. They are deleted once the deletion is confirmed there (irreversible). |

Without `--yes`, it asks which one you want.

**Why the server cannot delete them itself:** the keys stored on the server can add backups, not delete them on request. The only deletion they take part in is the weekly pruning by your retention, in a one-hour window ([pruning](/docs/storage#pruning)). That is what protects your backups if someone takes over the server. So deleting always ends with a signed-in confirmation in the dashboard. You can also skip the command and delete the server there directly.

Before you uninstall without `--keep-config`, check that the recovery key you keep still opens these backups:

```sh
neverwiped recovery-key check
```

Once `/etc/neverwiped` is gone, only that key can read them.

### Keep the configuration

To keep the configuration and the local key, so that a reinstall picks up where it left off:

```sh
neverwiped uninstall --yes --keep-config
```

On a copied machine (cloned VM, copied `/etc/neverwiped`), uninstall removes only the local copy. It tells the platform nothing and asks for no deletion, because the backups belong to the original server.
