Operations

Migrations and upgrades

Schema migrations and upgrade playbooks.

Spectron bundles per-Context schema migrations into the binary and applies them automatically. This page explains how migrations work and what to expect during version upgrades.

Each Context database is created from schema bundled into the server binary. Migrations are append-only — applied on context creation and, for existing Contexts, rolled out after a binary upgrade by the scheduler and workers (not as a blocking startup sweep).

  1. Every role rolls to a binary that embeds migrations V1…Vn.

  2. The elected scheduler ticks periodically and, for each Context whose schema_version is behind the binary's latest, enqueues a context_migrate job.

  3. A worker takes a per-Context migration lease, runs the pending migrations, and stamps schema_version monotonically.

Rollout time therefore scales with the job queue, not with a single-pod startup loop. Management API / gRPC GET /migrations (and the equivalent gRPC RPC) expose a version histogram, Contexts still behind, and DLQ entries so operators can watch catch-up.

Applied versions are tracked in each Context database. Cadenced per-Context maintenance (consolidate, elaborate, and similar) waits until that Context's migrations are ready.

Most upgrades are additive (new tables, fields, indexes). A minority include destructive steps (dropping retired tables or fields). Always take a SurrealDB backup before upgrading production Contexts.

After upgrades that change scope semantics, audit clients that pass multi-path flat arrays: ["a", "b"] is now OR, not AND — use [["a", "b"]] for conjunction.

Downgrading after a destructive migration is not supported — the older binary may not start against the new schema.

Spectron is a horizontally scalable application server – all durable state lives in SurrealDB. A rolling upgrade works as follows:

  1. Deploy the new Spectron binary (or container image) alongside the running version.

  2. Route traffic to the new version. The scheduler begins detecting behind Contexts; workers apply pending migrations asynchronously.

  3. Watch GET /migrations (or logs) until the behind set is empty before relying on schema that only the new version understands.

  4. Shut down the old version when traffic and migration catch-up look healthy.

Because replicas do not cache durable state in-process, you do not need to drain in-flight requests beyond what your load balancer already provides. In-flight document processing jobs are stored in SurrealDB and will be picked up by workers on the new version.

For single-server deployments (api + worker + scheduler in one process or compose stack):

  1. Take a SurrealDB backup of all Context databases (see Backups and retention).

  2. Stop the Spectron service.

  3. Replace the binary or pull the new container image.

  4. Start the service and watch logs / GET /migrations until Contexts reach the new schema version.

  5. Run smoke tests against a non-production Context before routing production traffic.

After upgrade, confirm Contexts are at the binary's latest schema version via GET /migrations or server logs. Failed migrations land on the job DLQ; Spectron will not treat that Context as migration-ready until the schema is consistent and the job succeeds.

Spectron versionSurrealDB versionNotes
Current3.1.xRequired for vector indexes and record types used by the schema

Always upgrade SurrealDB and Spectron together according to the release notes for your distribution.

After additive migrations, an older Spectron version may continue to run against a newer schema — it simply ignores tables and fields it does not know about. That does not apply once a destructive migration has run.

docker pull ghcr.io/surrealdb/spectron:latest
docker compose down
docker compose up -d
docker compose logs spectron | grep -i migration

Update the image tag in your deployment manifest, then roll out:

kubectl set image deployment/spectron \
  spectron=ghcr.io/surrealdb/spectron:latest
kubectl rollout status deployment/spectron

Pods come up without blocking on a full-fleet migration sweep. The scheduler enqueues catch-up jobs; workers apply them. Confirm the behind set empties via GET /migrations.

Replace the spectrond binary (see Bare metal), then restart the service:

sudo systemctl restart spectrond
journalctl -u spectrond -f

Downgrade only when no destructive migration has been applied since your backup. If the newer version dropped or reshaped tables, run the restore workflow in Backups and retention rather than starting an older binary against the live database.

Before upgrading, take a SurrealDB backup of each Context database:

surreal export \
  --conn ws://localhost:8000 \
  --user root --pass secret \
  --ns acme --db prod \
  pre-upgrade-backup-$(date +%Y%m%d).surql

Store the backup externally. The full backup and restore workflow is in Backups and retention.

Was this page helpful?