Deployment
Upgrades & migrations
Zero-downtime version upgrades: automatic migrations, the readiness probe, rolling deploys, and safe rollback.
This page describes core gm-server upgrade patterns. PostgreSQL can support a
rolling deployment when migrations are backward-compatible and the exact
release pair has been validated; this is not a full-stack availability SLA.
What happens on upgrade
When a new binary opens an existing database it runs any pending schema migrations automatically - you don't run a separate migrate step.
- Stepwise and transactional. Migrations apply in order, each in its own transaction. A failure rolls that step back cleanly; the database is never left half-migrated.
- Auto-snapshot first (SQLite). Before applying migrations to existing data, Meivo writes a
<db>.pre-v<N>.baksnapshot next to the database, so a bad upgrade is instantly recoverable. - Downgrade protection. If a database has a newer schema than the binary understands (for example after a rollback), Meivo refuses to open it with a clear message instead of silently operating on - and corrupting - an unknown schema.
Readiness for rolling deployment
The server exposes two probes:
| Endpoint | Meaning | Use for |
|---|---|---|
GET /v1/healthz | process is up (liveness) | restart-on-crash checks |
GET /v1/readyz | storage reachable and migrated (readiness) | load-balancer / rolling-deploy health checks |
readyz returns 200 only once the new instance can actually serve, and 503 while it is starting up or migrating. Both probes are always unauthenticated, so they work even with GM_API_KEYS set.
Point your platform's health check at /v1/readyz. During a rolling deploy the orchestrator starts the new instance, waits for readyz to go green, shifts traffic, then drains and stops the old one - so requests are only ever sent to an instance that's ready.
Rolling upgrades by backend
PostgreSQL rolling-upgrade pattern
PostgreSQL deployments can run several instances against one database, so a standard rolling pattern may be used after migration compatibility testing:
- Roll out the new version one instance at a time (ECS/Cloud Run/Container Apps do this by default; set the health check to
/v1/readyz). - The first new instance applies any pending migrations on startup; the others see an up-to-date schema.
- Old and new instances briefly run side by side - which is safe as long as migrations are additive (see below).
SQLite (single-writer → brief restart)
A SQLite database is a single file with a single writer, so you run one instance. Upgrades require a restart: the process stops, the new binary opens the file, migrates it, and starts. Measure the maintenance window under your own data and storage conditions.
The additive (expand/contract) rule
So that an old and a new version can coexist during a rollout, schema changes are additive: new tables and new nullable/defaulted columns, never a rename or drop in the same release. A column that must change shape is handled across two releases - add the new shape and write both (expand), migrate readers, then remove the old shape later (contract). Meivo's own migrations follow this rule; keep it in mind if you fork or extend the schema.
Rolling back
- Stop the new version.
- Postgres: if the new version added only additive changes, the old binary
keeps working against the migrated schema - just redeploy it. If a migration
was not backward compatible, restore your managed-database snapshot or
pg_dumpbackup before starting the old version. - SQLite: with the service stopped, restore the
<db>.pre-v<N>.baksnapshot that the upgrade wrote (or an operator-created SQLite backup), then start the old binary. The downgrade guard ensures the old binary won't touch a database it doesn't understand.
Before a major upgrade - checklist
- Take an explicit backup. For SQLite, use SQLite's online-backup tooling or
stop the service before copying
<GM_DATA_DIR>/greatmemory.db. For Postgres, use a managed snapshot orpg_dump. - Confirm your health check targets
/v1/readyz. - Pin the image to an explicit version tag rather than
latest, so rollouts and rollbacks are deterministic. - Upgrade one environment (staging) first and watch
GET /v1/stats; verify counts, audit backlog, latency, and workload-specific memory baselines.
For the three-service enterprise product, also validate the compatibility,
database migrations, provider-encryption secrets, and rollback procedure for
gm-ingest-svc and gm-webui.