# Upgrading

Upgrading cronpad means replacing the binary or image and restarting. Database migrations run automatically on start. Because only one process may own the database, an upgrade is a stop-then-start, which pauses scheduling for a few seconds; runs due in that window fire as soon as the new version is up.

## Steps

1. Read the release notes for the versions you're skipping.
2. Make sure Litestream replication is healthy (or take a copy of the data directory).
3. Verify the release archive against `checksums.txt` and review its SPDX SBOM if installing a binary. Replace the image tag or binary and restart (`docker compose pull && docker compose up -d`, or roll out the new image with `strategy: Recreate`).
4. Watch the logs for `server started` and check `/readyz`.

## Versioning

- cronpad follows semantic versioning. Minor and patch releases are drop-in.
- Major releases may change configuration or the API. `/api/v1` stays compatible for as long as it exists; breaking API changes get a new version path.
- Migrations only move forward. To roll back to an older version after a migration, restore the database from before the upgrade.

## Running migrations separately

If you set `database.run_migrations = false`, run them yourself before starting the new version:

```sh
cronpad migrate --config /etc/cronpad/cronpad.toml
```