Upgrading BenchDB¶
This page is for operators moving a BenchDB server to a newer version. It
covers the normal in-place upgrade, rolling back, and rebuilding databases from
early private builds. Keep PostgreSQL and its managed Parquet archive together
through backup, restore, and deployment.
Operations describes exactly what
benchdb migrate checks and applies.
How versions and migrations work¶
Stable releases publish the server image as ghcr.io/kenn-io/benchdb:<tag>,
for example ghcr.io/kenn-io/benchdb:v1.2.3. Each release's workflow summary
records the image digest. Pin deployments to that digest. See
Releases and CI. Until the first release,
build the image from a commit on main.
The schema is a numbered series of SQL migrations embedded in the binary,
starting from the 000001_initial_schema baseline. Pull request #2 reset the
schema history to that baseline on 30 August 2026. Since then, a migration
never changes once it is on main, and make migration-history-check enforces
that in CI. Schema changes add a new numbered migration instead. A database
created by a build that includes the reset upgrades in place with
benchdb migrate. An older database needs the
one-time rebuild.
BenchDB has no down-migration command. The rollback path is the backup you take before migrating.
Upgrade in place¶
- Choose the new image and note its digest. For a release, copy the
ghcr.io/kenn-io/benchdb@sha256:...reference from the release workflow summary. Retain the current image or binary for rollback. - Stop every server and result publisher. Keep them stopped through backup and migration. A running server's status worker takes work from the queue that migrations fill. An old server would score re-queued statuses with its old rules and remove them from the queue, and the new server would not score them again.
-
Take an owner-private recovery backup that includes the database schema, data, and migration history:
umask 077 pg_dump --format=custom --no-owner --no-acl \ --file benchdb-before-upgrade.dump "$BENCHDB_DB_URL"If the source already uses managed Parquet storage, also back up the complete
BENCHDB_DATA_DIRwhile the server remains stopped. Include its measurement files, catalogs, anddatasetidentity file:pg_dumpdoes not include Parquet files. The database and archive backups must come from the same stopped deployment. For the first managed-Parquet upgrade, the database backup contains all measurements; provision an empty persistent local archive directory for the new server.Attachment bytes in the artifact bucket need their own backup; see Attachment storage.
-
Run the new image's
benchdb migratewithBENCHDB_DB_URLset, and wait for it to finish:It prints
database schema is currenton success. On failure it exits non-zero. Do not start the new server. Fix the cause, or roll back. -
Start the new server version with its persistent archive mounted at
BENCHDB_DATA_DIR. Do this only aftermigratesucceeded. - Check the new server.
benchdb health --server <url>printsok, andGET <url>/api/pingreturns the new build's commit inrevision. Check representative result, history, series, run, and report pages. Keep the backups until the upgraded deployment has accepted and displayed new results.
Some migrations re-queue stored run verdicts and benchmark statuses. The server recomputes them in the background after it starts. Until it finishes, the Benchmarks page reads "Updating statuses…".
Operations describes how each deployment setup runs migrations before serving:
- In Kubernetes, scale the Deployment to zero, run
run_migrationsfromscripts/go_deploy_runtime.shin a subshell, and rundeployonly if it succeeded. See Kubernetes. - In the Umbrel Compose example, a
migrateservice runs first, and the server waits for it to exit successfully. Change the pinned image digest and restart the app after taking the paired backup above. See Umbrel deployment.
Roll back¶
Restore the database, its matching archive, and the previous image together.
Rolling back only the image is not enough. An older binary's benchdb migrate
refuses a newer schema with database schema version N is newer than this
binary (expects M); upgrade BenchDB. benchdb serve does not check the schema
version, so an old server could attempt to use a schema it was not built for.
- Stop the new server and every result publisher.
-
Restore the full recovery dump into an empty database. Do not run migrations on the empty database first:
-
If the source used managed Parquet storage, extract the matching archive backup into an empty directory and give the server write access to it:
-
Point
BENCHDB_DB_URLat the restored database and, for an archived source,BENCHDB_DATA_DIRat the restored archive. Deploy the previous image digest and verify the same pages. To retry an upgrade, apply the new binary's migrations to this restored pair before starting the new server. When retrying the first managed-Parquet upgrade, use an empty archive directory.
A data-only restore into a freshly migrated database is not this recovery
procedure. Migration 13 seeds the singleton archive_dataset row, so restoring
that row again conflicts. Omitting it instead loses the identity that ties the
archive to its database. The full dump restores the original schema and
identity together.
Results written after the backup are not in the restored deployment.
Kubernetes' rollback function runs kubectl rollout undo on the Deployment
only. It does not restore the database or archive.
Rebuild a database from a pre-reset build¶
Private experimental builds from before the 30 August 2026 reset used several
temporary database layouts. They are not supported upgrade sources. Do not run
benchdb migrate against one. If the database has no migration ledger,
benchdb migrate refuses it with existing experimental database must be
exported and rebuilt from the current BenchDB baseline. If it has a ledger,
benchdb migrate cannot tell it apart, so check which build created it.
These databases need a conversion specific to their source schema. A generic data-only restore into the current schema is not a supported upgrade. Never change the migration ledger by hand.
Stop BenchDB and all result publishers. Before attempting the conversion, retain the old image or binary and take an owner-private full recovery backup:
umask 077
pg_dump --format=custom --no-owner --no-acl \
--file benchdb-recovery.dump "$OLD_BENCHDB_DATABASE_URL"
Before switching traffic to the rebuilt deployment, check representative result, history, series, run, and report pages. Keep the recovery backup until the rebuilt deployment has accepted and displayed new results.