Skip to main content
Levelrail tells you which managed databases are behind, which ones miss security fixes, and which run a release past its end of life. It can apply patch and minor releases for you inside a maintenance window. Every upgrade, automatic or started by hand, takes a fresh backup first, checks it, and reverts on its own when the new version does not come up healthy. Major upgrades are never automatic. For those, use the guarded Postgres major upgrade or restore a backup into a new database.

What the advisor shows

Open a database and select Upgrades, or run:
For each database you get:
  • The current version and release line, with its upstream end-of-life date and a status: supported, end of life soon (within APP_DB_EOL_WARN, default 180 days), or end of life.
  • The available targets, each marked patch, minor or major: the newest patch of your line, the newest release of each newer minor, and the newest release of each newer major line.
  • Security flags: a target that fixes a CVE affecting your current version is marked, with the CVE ids.
  • Blockers, such as a missing backup target or a database on another node.
The data comes from a curated catalog that ships with Levelrail (internal/dbupgrade/catalog.json): supported versions, release lines with end-of-life dates, and CVE ids per fixed version. Nothing is fetched while you load the page. A background job also reads the image tag list from Docker Hub once a day and adds newer pinned tags it finds; when the registry is unreachable the last good list is kept. Set APP_DB_VERSION_REFRESH_INTERVAL=0 to turn that off (for example on an offline host). A floating tag such as 16 could be any 16.x release, so it is treated as the oldest of its line, and upgrading pins it to an exact release. A pgvector variant (17-pgvector) and a non-numeric tag such as latest have no targets. The attention center shows N databases have security updates available, plus one item per database past end of life and per database whose last upgrade failed.

Automatic upgrades

A database without its own policy inherits the platform default (Settings > Database upgrades). A run only starts inside the window and only when at least APP_DB_UPGRADE_MIN_WINDOW_REMAINING (default 30 minutes) of it is left. A started run always finishes its safety steps, even past the window’s end. If an automatic upgrade to a version fails or is reverted, that version is not tried again automatically: start it by hand once you know why, or wait for a newer release. The database must have a backup target (scheduled backups set one). Without it no upgrade runs.

Upgrade now

POST /api/v1/databases/{name}/upgrade-now with {"version": "16.11", "confirm": "<name>"} runs exactly the same steps immediately, outside any window. Majors are refused. A version that is not in the catalog is still accepted when it is a newer patch or minor of the same line.

What a run does

Each run is stored in db_upgrade_runs and moves through these states. The state and the step inside it are saved after every step, so a control plane restart resumes the run where it stopped, and a shutdown in the middle of a step never marks it failed.
  1. pending: refuse when a restore or major upgrade of the same database is running.
  2. backing_up: take a logical backup to the database’s backup target, then download it again and verify its checksum, size and format (the same check as backups verify). A failure here ends the run with nothing changed.
  3. upgrading: pull the target image (a missing tag fails here, before any downtime), record the image the database runs now, stop the database and copy its data volume to a snapshot volume, then apply the new version through the same path as set-version.
  4. verifying: wait for the container to run the new image, then connect and run a query. Postgres must not be in recovery and Redis-family engines must report the master role. The reported server version must match the target.
When verifying fails within APP_DB_UPGRADE_HEALTH_TIMEOUT (default 5 minutes), the run reverts, cheapest path first, and records which path worked: If every path fails, the run ends failed with the snapshot volume and backup id in its reason, so you can restore by hand. With revert_on_failure off, a failed run leaves the database on the new version. The snapshot volume is removed when a run succeeds or reverts. The pre-upgrade backup stays, under its normal retention.

Engine behaviour

Upgrades run only for databases on the control plane’s own node. A database placed on another node shows that as a blocker.

Reference

API

Environment

Next steps

Managing databases

Versions, major upgrades, backups and restores.

Backups and storage

Set up the backup target every upgrade needs.
Last modified on October 12, 2026