# Restoring a backup taken on an older version

> A backup of an environment is always restored into a copy beside the database the environment serves. When the backup was taken on the version the environment serves, you switch onto the copy. When it was taken on another version, making the copy runnable is a second step that you choose: run it on its own version while the platform release it was served on is still offered, attempt to rebuild that version on the current platform release and migrate the copy forward, deploy your own build onto the copy, or download its data, reshape the rows yourself and load them into a new copy at the version the environment serves. Each is an attempt you are responsible for, and the platform does not promise it will work.

<!-- id: zones-restoring-a-backup-of-another-version · area: zones · stability: stable · html: https://osysharp.com/reference/zones/restoring-a-backup-of-another-version/ -->

## Summary        {#summary}

Restoring a backup of an environment has **two steps**, and the second one is yours to choose.

1. **The database is restored into a copy.** The environment's zone restores the backup into a new database beside the one
   the environment serves, and checks it against the rows the backup counted. The environment keeps serving its own
   database. The model of the version the backup was taken on is kept for as long as the backup can be restored.
2. **The copy is made runnable.** If the backup was taken on the version the environment serves, you switch the environment
   onto the copy. If it was taken on **another version**, the copy holds that version's tables, so serving the current version
   over it is refused. You choose one of these, on the application's **Backups** page:

   - **Run it on its own version** — offered while the platform release that version was served on is still offered. The
     environment is switched onto the copy and runs the backup's version on that release, as it was.
   - **Attempt a rebuild** — when that release is no longer available, the page says so ("v0.9.0 was built for platform
     0.8.0, which is no longer available"), and you may attempt to rebuild the backup's version on the release the
     environment runs now and migrate the copy forward to it. This is the platform's ordinary move to a release, run on the
     copy.
   - **Deploy your own build onto the copy** — `osy deploy --onto-restore <restore>`. Your build is compiled into the model
     of the version the copy holds, and the copy is migrated to it.
   - **Reshape the data yourself** — download the copy as rows (one file per table, in the format `osy import` reads) or as
     a Postgres dump, change the rows with whatever tools you like, and load them back. They go into a **new** copy at the
     version the environment serves, checked row by row; you then switch onto it as on any restore of that version.

## Description    {#description}

**Every option is an attempt you choose and are responsible for.** Compatibility with the restored data cannot be
guaranteed: only the source as it was when the backup was taken can be relied on to match it. A forward migration may fail,
or complete and leave incompatibilities you must resolve yourself. The page shows this before it offers any attempt, and no
attempt starts until you tick that you have read it.

What an attempt does, and does not do:

- Its dry run and its migration run on the **copy**, in one transaction. Nothing backs up, migrates or otherwise touches the
  database the environment serves.
- The environment is switched onto the copy only when the attempt's deployment is placed. If that rollout then fails, the
  environment is switched back to the database it served before, and rolled back onto the version it ran.
- A failed attempt is recorded on the restore with what failed. The copy is kept, so you can look at it, try another
  attempt, or discard it.
- Once an attempt converges, the environment runs the attempt's version over the restored data. Whether the application
  works with that data is yours to check; to move it on to your current version, deploy that version as usual.

Who may choose: an owner or admin of the application's organization, or a member of the application who is not only a
developer. A deploy onto a copy (`--onto-restore`) is held to the same rule, because it switches the environment.

### Reshaping the data yourself {#reshaping-the-data-yourself}

**Downloading.** `osyrin app restore-download --restore <restore>` asks the environment's zone to export the restored copy
and downloads it straight from the zone; `--dump` downloads a Postgres dump (custom format, for `pg_restore`) instead of rows.
The rows are written as the copy holds them, on the version the backup was taken on: every table of the application's data,
keyed on each row's id, with each reference written as a lookup by id, so rows keep their ids and links when they are loaded
back. A README in the download lists anything not carried, such as vector columns, which are recomputed rather than stored.

**Loading.** `osyrin app restore-load --restore <restore> --rows <zip or folder>` uploads the rows straight to the zone and asks
for them to be loaded:

- **Only rows are accepted.** An upload holding anything but `.json` row files is refused by name, and nothing in it is run.
  No SQL or schema change is ever taken from an upload: the new copy gets the structure of the database the environment
  serves, from the platform.
- The rows are loaded into a **new database beside the environment's**, through the model of the version it serves, so
  every value is type- and constraint-checked as an import is. If any row does not fit, nothing is kept: the new copy is
  dropped, and every row that did not fit is reported by entity, row and reason on the restore and on the Backups page.
- The upload counts against the application's storage allowance, and one upload holds at most 256 MiB.
- The environment goes on serving its own database. Switching onto the new copy is a separate step, offered on the Backups
  page after the same caveat as every other choice here.

Loading rows is an attempt like the others: whether the reshaped data works with the version is yours to check, and the
platform makes no promise that it will.

## Examples       {#examples}

```console
osy deploy --env prod --server https://osyrin.app --onto-restore 3f1c…   # your build, onto the restore's copy of prod
```

```console
osyrin app restore-download --restore 3f1c… --out rows.zip        # the copy's rows, one file per table
osyrin app restore-load --restore 3f1c… --rows ./reshaped        # load the reshaped rows into a new copy beside prod
osyrin app restore-switch --restore 9a07…                         # once loaded: switch prod onto the new copy
```

## See also       {#see-also}

[Upgrading an application to a newer platform release](https://osysharp.com/reference/zones/upgrading-an-application/) — the move to a release that a rebuild attempt runs on the copy.

[Deploying your app to an environment](https://osysharp.com/reference/local/deploying-your-app/) — `osy deploy`, and its `--onto-restore` option.

[Deploying an application to a cloud platform — the zone builds it](https://osysharp.com/reference/zones/deploying-an-application/) — how a zone builds and rolls out a deploy.
