• Start

Rollouts

Rollouts provide a controlled, phased migration workflow for shared and production SurrealDB databases, with review, staged execution, and rollback support.

Rollouts are SurrealKit's migration system for shared and production databases. Rather than immediately pushing all changes (as Sync does), Rollouts generate a reviewed manifest and apply it in two phases: an expand phase that adds new definitions without breaking existing consumers, and a contract phase that removes old ones after your application has been updated. Deploying schema and application changes separately means no downtime.

A complete rollout has three stages:

  1. Start: applies non-destructive changes: adding tables, fields, indexes, and access methods that new application code will use. The old application code continues to work alongside the new definitions.

  2. App cutover: you deploy the new version of your application. Both old and new application code remain compatible with the database during this window.

  3. Complete: applies destructive changes: removing legacy tables, fields, or indexes that are no longer needed. Only run this after the new application version is stable.

If you are adopting SurrealKit on a database that already exists, capture a baseline before planning any rollout:

surrealkit rollout baseline --user root --pass secret

This reads the current database schema and writes snapshot files to database/snapshots/. Future plans diff against this baseline. You only need to run this once.

After editing your schema files, plan a rollout:

surrealkit rollout plan --name add_customer_indexes

SurrealKit computes the diff between the current snapshot and your schema files, then generates a timestamped manifest in database/rollouts/:

database/rollouts/20260302153045__add_customer_indexes.toml

Review this file before proceeding. It lists each step, the SQL it will execute, and which phase (start or complete) it belongs to. Commit it to your repository alongside your schema changes.

surrealkit rollout start 20260302153045__add_customer_indexes --user root \
--pass secret

This applies all start-phase steps. SurrealKit records resumable state in the __rollout metadata table, so if the process is interrupted it can pick up where it left off. Only one rollout can be in progress at a time; concurrent starts are blocked.

After start completes, deploy the new version of your application. At this point both the old and new schema definitions coexist in the database.

Once the new application version is healthy:

surrealkit rollout complete 20260302153045__add_customer_indexes --user root --pass secret

This applies all complete-phase steps (removing legacy definitions) and marks the rollout as done.

If something goes wrong after start but before complete, you can undo the start-phase changes:

surrealkit rollout rollback 20260302153045__add_customer_indexes --user root --pass secret

Rollback reverses what start applied. It is not available after complete has run, so verify your application is working correctly before calling complete.

Inspect the state of rollouts stored in the database:

surrealkit rollout status --user root --pass secret

Validate a manifest file without connecting to the database or applying anything:

surrealkit rollout lint 20260302153045__add_customer_indexes --user root \
--pass secret

This is useful in CI to catch manifest errors before they reach a shared environment.

If rollout complete (or rollback) is killed mid-flight, the __rollout row can be left in an intermediate state (running_complete, running_rollback, or running_start) even though the schema changes have already been applied. Re-running complete or rollback will not always heal the metadata, because the underlying SQL steps are already done, and the stuck rollout blocks any new one from starting.

Use repair to finish the metadata transition without re-running any SQL:

surrealkit rollout repair 20260302153045__add_customer_indexes --user root --pass secret

The behaviour depends on the stuck state:

Stuck stateRepair result
running_completeFlips to completed and restores the target entities
running_rollbackFlips to rolled_back and restores the source entities
running_startFlips to failed; re-run start (idempotent) or rollback

Repair never re-executes per-step SQL. It only reconciles the __rollout and __entity tables so subsequent sync and plan runs see a clean state.

Each rollout transitions through the following states, recorded in the __rollout table:

planned → running_start → ready_to_complete → running_complete → completed

└── running_rollback → rolled_back
StateMeaning
plannedManifest exists; neither start nor complete has run
running_startStart phase is in progress or was interrupted
ready_to_completeStart phase completed successfully
running_completeComplete phase is in progress or was interrupted
completedBoth phases completed (terminal)
running_rollbackRollback is in progress or was interrupted
rolled_backStart phase was reversed (terminal)
failedA phase failed; recover with rollback or repair

completed and rolled_back are terminal. The running_* states and failed are stuck states left by an interrupted run; recover them with repair. Only one rollout may be in a non-terminal state at a time.

PathDescription
database/rollouts/*.tomlGenerated rollout manifests; commit these
database/snapshots/schema_snapshot.jsonSchema state snapshot used for diffing
database/snapshots/catalog_snapshot.jsonCatalog snapshot
  • Template Variables: parameterise schema files for different environments

  • Testing: validate schema and permissions before promoting a rollout

Was this page helpful?