ParadeDB upgrade for existing databases
Production and development Compose in this repository use paradedb/paradedb:v0.25.11-pg17. This document covers 0.22.x → 0.25.11 with PostgreSQL major version staying at 17; it is not a PostgreSQL major-version upgrade, and other old Helm versions are not covered as-is.
Compared to v0.22.6-pg17, this line brings PostgreSQL 17.9 → 17.11, pgvector 0.8.1 → 0.8.4 (fixes parallel HNSW build buffer overflow and HNSW vacuum index corruption), and WAL-based crash recovery for pg_search (from 0.24.0, see paradedb#4901).
WARNING
After replacing the image you must upgrade the extension catalog to match the image. If the catalog stays on an old version, some extension SQL functions (e.g. paradedb.version_info()) can segfault due to signature mismatch with the new binary, crashing the PostgreSQL instance and entering recovery. Also do not run ALTER EXTENSION pg_search UPDATE TO '0.22.6' on the new image—that causes the same mismatch.
Upgrade steps
Run all commands from the repository root. For development, database commands use docker compose -f docker-compose.dev.yml; stop the dev backend on the host manually—dev Compose has no app service. Keep the data volume: do not run down -v, delete the volume, or switch to a PG18 image.
Stop app and any other writers to the database; if Langfuse is enabled, stop web/worker; stop a local dev backend if running.
bash# Standard deploy; in dev, stop backend on host docker compose stop app # Only if Langfuse is enabled docker compose stop langfuse-web langfuse-workerBack up all databases and roles, including Langfuse, and verify restore. Store backups outside the database data volume.
bashumask 077 docker compose exec -T postgres sh -c 'pg_dumpall -U "$POSTGRES_USER"' > paradedb-before-upgrade.sqlIf the old image cannot start on the current CPU, snapshot the stopped data volume first, produce a logical backup on a compatible machine or validate snapshot restore, then change the only copy of the data.
With updated Compose, replace only the database container:
bashdocker compose pull postgres docker compose up -d --no-deps --wait postgresComplete SQL extension upgrade. Replacing the image alone does not update
pg_extensionin existing databases. The new image includes the full upgrade script chain from 0.22.x; any 0.22.x can step up to the image default in one go:bashdocker compose exec -T postgres sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1' <<'SQL' ALTER EXTENSION pg_search UPDATE; ALTER EXTENSION vector UPDATE; SELECT extname, extversion FROM pg_extension WHERE extname IN ('pg_search', 'vector'); SELECT * FROM paradedb.version_info(); SQLRun the same in any other database where
pg_searchorvectoris installed, includingpostgres, template databases, or Langfuse. Do not install extensions on databases that do not need them.pg_searchcatalog andparadedb.version_info()should report 0.25.11;vectorshould be 0.8.4.Restart writers, confirm GsKnora migration status, run representative keyword and vector search. Existing BM25 and HNSW indexes remain readable/writable on the new version without full re-import; use
REINDEXif needed. Keep backups until validation finishes.
Scope of automatic migrations
GsKnora startup migrations upgrade extensions only in the GsKnora database, respect app.skip_embedding, do not install missing extensions, do not downgrade, and do not handle other version lines:
000115: installedpg_search0.22.0–0.25.10 and server offers 0.25.11 → upgrade to 0.25.11; installedvector0.8.0–0.8.3 and server offers 0.8.4 → upgrade to 0.8.4.000099: historical; only when the server provides extension package 0.22.6 (still onv0.22.6-pg17image) to move 0.22.2–0.22.5 → 0.22.6; skipped on the new image, handled by000115.
If these migrations ran before replacing the database image, they will not run again automatically after the new image—you must run the SQL above. Older app versions without matching migrations need manual upgrade too. Extensions in other databases are not managed by GsKnora migrations.
Rollback and isolated validation
Rollback means restoring the pre-upgrade backup/snapshot to an isolated volume with the old image. Reverting only the image tag does not undo extension SQL changes; from pg_search 0.24, custom WAL resource manager records prevent replay on the old image. Migration down files do not downgrade extensions.
The repository provides an isolated validation script (default 0.22.2 → 0.25.11, or --to 0.22.6 for historical patch upgrade):
docker pull paradedb/paradedb:v0.22.2-pg17
docker pull paradedb/paradedb:v0.25.11-pg17
python3 scripts/test_paradedb_upgrade.pyThe script uses temporary containers and volumes without mapped ports; it validates same-volume upgrade, table content, keyword/vector search, migration idempotency, and post-restart results, with backup and logs. Fixed test data only—in production, validate your data and search load too.