
# Upgrade and roll back a Sovrium app

Schema migrations are **forward-only** — a released migration is never rewritten, and there is no automatic downgrade. So a safe upgrade always pairs with a backup you can restore.

## Upgrade

Back up first ([SQLite](/en/docs/backup-restore-sqlite), or a database snapshot on Postgres), then move to the new version and restart. The schema migration runs on boot, inside a transaction, before the app serves traffic:

```bash
sqlite3 .sovrium/database.db ".backup '/backups/pre-upgrade.db'"
sovrium update            # binary install; or: docker pull ghcr.io/sovrium/sovrium:latest
sovrium stop && sovrium start app.ts
```

If the migration fails, the transaction rolls back and the server refuses to start on an inconsistent schema — you are never left half-migrated.

## Roll back

Because migrations don't reverse, a rollback restores the pre-upgrade data alongside the prior binary/image:

```bash
sovrium stop
# reinstall the previous version (pin the tag / binary you upgraded from)
cp /backups/pre-upgrade.db .sovrium/database.db && rm -f .sovrium/database.db-wal .sovrium/database.db-shm
sovrium start app.ts
```

For **zero-downtime**, run the new version as a second instance behind your proxy, verify it, then switch traffic — keeping the old instance until you're confident.

## Next

- [Schema Migrations](/en/docs/migrations) — why released migrations are immutable.
- [Back up & restore SQLite](/en/docs/backup-restore-sqlite) — the backup this guide relies on.
- [CLI Reference](/en/docs/cli) — `update`, `stop`, and `start`.
