# Restore points

> Name a moment before a risky change, so you can restore exactly to it later.

Source: https://rowsafe.sh/docs/concepts/restore-points

A **restore point** gives a moment a name. `before-drop-legacy-orders` is much easier to find at 3 a.m. than a timestamp. If a change goes wrong, you can restore to exactly that point: everything committed before it is there, nothing after it.

Create one right before a migration, a backfill, a bulk delete, or anything an AI agent is about to run:

```sh
rowsafe mark app before-migration-42
```

Rowsafe waits until the point is safely in your bucket before it returns, usually within a few seconds.

## Names

- 1 to 63 characters: lowercase letters, digits, `-` and `_`, starting with a letter or digit.
- Unique per database.
- Without a name, `rowsafe mark app` uses `manual-<UTC time>`, for example `manual-20260924-140500`. Restore points created by AI agents are named `agent-<UTC time>` by default.

In a project with a [`.rowsafe.json`](https://rowsafe.sh/docs/reference/cli#rowsafejson), you can leave out the database: `rowsafe mark before-drop`.

## List them

```sh
rowsafe marks app
```

```text
NAME                 STATUS    CREATED              RESTORE FROM BACKUP  LSN         BY
before-migration-42  archived  2026-09-24 14:05:12  20260921-010002F     0/5A000090  key:key_... (CLI · rowsafe CLI on laptop)
```

| Status        | Meaning                                                                                                                                                         |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `archived`    | Confirmed in your bucket. Safe to restore to.                                                                                                                   |
| `unconfirmed` | Written, but archiving didn't confirm it within the timeout (90 seconds by default). Usable only if the archive has since moved past it. You also get an alert. |
| `pending`     | Being created.                                                                                                                                                  |

**Restore from backup** is the newest backup that finished before the point was created. You need it to restore to the point: see [Restore to a restore point](https://rowsafe.sh/docs/guides/restore#to-a-restore-point).

## Good to know

- Restore points are cheap: two SQL calls and one WAL segment on PostgreSQL.
- They need an `active` database (archiving proven).
- They don't pause or wait behind a running backup or drill.
- Creating one is recorded in the [audit log](https://rowsafe.sh/docs/guides/teams#audit-log) with who created it.
- A restore point doesn't restore anything by itself. It marks a moment you can restore to.

> **On PostgreSQL:** Rowsafe calls `pg_create_restore_point(name)`, then `pg_switch_wal()`, and waits until the segment holding the point is archived.
