Migrations
Sp00ky includes a built-in migration system for managing incremental, version-controlled changes to your SurrealDB schema. Instead of applying your full schema on every deploy, migrations let you evolve your database safely over time — locally, in CI, and on Sp00ky Cloud.
How It Works
- You write your schema in
.surqlfiles - When you change the schema,
spky migrate creatediffs your source against the current migrations and generates a new migration file spky migrate applyruns any pending migrations in order against your database- Each applied migration is tracked in a
_00_migrationstable with a SHA-256 checksum, so drift and re-application are detected automatically
Migrations are applied individually (SurrealDB DDL does not support transactions). All generated DEFINE statements include the OVERWRITE keyword for idempotency.
Migration Engine
Sp00ky supports two migration engines. Set migrationEngine in your sp00ky.yml to choose:
| Engine | Description |
|---|---|
legacy | (default) Built-in engine with auto-diff, SHA-256 checksum tracking, and ephemeral SurrealDB for schema comparison. Described in detail below. |
surrealkit | Delegates to the external SurrealKit CLI. Uses surrealkit sync (declarative push) during spky dev and surrealkit rollout (phased migrations) for production deploys. |
When using surrealkit, install it with cargo install surrealkit or set the binary path in sp00ky.yml. The CLI verifies the binary exists before running any migration command.
The rest of this page documents the legacy engine. If you’re using SurrealKit, refer to the SurrealKit documentation for engine-specific commands — all spky migrate subcommands (create, apply, status, fix) are routed through whichever engine you’ve selected.
Creating Migrations
Auto-Diff (Recommended)
The primary way to create a migration is auto-diff — Sp00ky compares your current source schema against the state defined by existing migrations and generates only the changes:
Under the hood this:
- Builds the new schema from your source files (schema + backend method schemas)
- Replays all existing migrations through an ephemeral SurrealDB to get the old schema
- Diffs old vs new to find additions, removals, and modifications
- Writes only the diff as a new migration file with
OVERWRITEstatements
If there are no changes, it prints a message and creates nothing.
Example output:
Auto-diff requires Docker to be running — it uses an ephemeral SurrealDB container for schema normalization.
Auto-Diff Against a Live Database
If you have a running SurrealDB, you can diff against it directly instead of replaying migrations:
This extracts the live schema and diffs it against your source — useful when the database has drifted from what migrations expect.
Empty Migration
For manual control, create an empty migration template:
This creates a file with a placeholder comment that you fill in yourself.
From Existing Schema
If you’re bootstrapping migrations for the first time, prepopulate from an existing schema file:
For the very first migration, the full schema is the incremental change from an empty database, so this is typically used as-is.
Migration File Format
Files follow a strict naming convention:
Each file contains SurrealQL statements. Auto-generated migrations include OVERWRITE for idempotency:
The name is automatically sanitized — spaces and hyphens become underscores, uppercase becomes lowercase, and special characters are stripped.
Applying Migrations
Run all pending migrations against your database:
Migrations execute in timestamp order. Each applied migration is recorded in the _00_migrations tracking table with its version, name, timestamp, and SHA-256 checksum.
Connection Options
All connection flags can also be set via environment variables:
| Variable | Default | Description |
|---|---|---|
SURREAL_URL | http://localhost:8000 | SurrealDB endpoint |
SURREAL_NS | main | Namespace |
SURREAL_DB | main | Database |
SURREAL_USER | root | Username |
SURREAL_PASS | root | Password |
CLI flags take precedence over environment variables.
Checking Status
Example output:
Status detects:
- Pending — migration exists on disk but hasn’t been applied yet
- Drift — a migration file was modified after it was applied (checksum mismatch)
- Missing — a migration was applied but the file no longer exists on disk
Fixing Drift
When checksums don’t match (e.g., you intentionally edited an applied migration), use the fix command:
This does two things:
1. Updates checksums — For each applied migration where the on-disk file has changed, the stored checksum is updated to match the current file content.
2. Detects schema drift — Replays all migrations through an ephemeral SurrealDB, then compares the expected schema against your live database. If they differ, it generates a corrective migration:
Always review generated corrective migrations before applying — they may contain destructive changes like REMOVE FIELD statements.
Migrations During spky dev
When you run spky dev, the CLI handles migrations automatically:
1. Schema drift check — Before starting infrastructure, Sp00ky diffs your source schema against existing migrations. If changes are detected, you’re prompted to generate a new migration:
2. Apply pending migrations — After infrastructure starts and SurrealDB is healthy, pending migrations are detected. You’re prompted to apply them:
If migration application fails (e.g., syntax error in a migration), you can choose to reset the database and retry.
Flags
| Flag | Effect |
|---|---|
--skip-migrations | Skip the entire migration phase |
--apply-migrations | Auto-apply pending migrations without prompting |
--fix-checksums | Auto-fix checksum mismatches before applying |
3. Internal schema — After user migrations, Sp00ky automatically applies its internal schema (meta tables, per-table events for record versioning, and remote functions). This is idempotent and not tracked in _00_migrations.
Migrations During Cloud Deploy
When you run spky deploy, migrations are applied automatically as part of the deployment flow:
- Infrastructure is provisioned (SurrealDB, SSP, Scheduler VMs)
- The CLI waits for SurrealDB to become reachable on its public URL
- Migrations are applied from your local
migrations/directory against the cloud database - Internal schema and remote functions are applied to the cloud SSP/Scheduler
- Deployment is finalized and app containers start
No user interaction is needed — migrations run automatically. If your migrations/ directory doesn’t exist, the migration step is skipped.
Cloud deploy applies migrations from your local machine to the cloud database. Make sure your local migrations directory is up to date before deploying.
The same migration flow also runs after spky backup reset — after the database is wiped, migrations are re-applied to rebuild the schema.
Safety Features
- SHA-256 checksums — Every migration is hashed when applied. Modifications after application are detected and block further applies until resolved.
- Drift detection —
statusandfixdetect when applied migrations have been modified or when the live database has diverged from what migrations define. - Ordered execution — Migrations always run in chronological order by their timestamp prefix.
- Idempotent generation — Auto-generated migrations use
DEFINE ... OVERWRITEso they can be safely re-applied if needed. - Unique tracking — The
_00_migrationstable has a unique index onversion, preventing duplicate application.
SurrealDB DDL does not support transactions. If a migration fails partway through, the database may be in a partial state. Use spky migrate fix to detect and correct drift.