Migrations let you run one-time tasks safely on application startup — such as evolving database schemas, backfilling data, or initializing external services like Stripe plans.Documentation Index
Fetch the complete documentation index at: https://docs.modelence.com/llms.txt
Use this file to discover all available pages before exploring further.
Defining Migrations
Pass amigrations array to startApp(). Each migration has:
version- Unique numeric versiondescription- Human-readable summaryhandler- Async function that performs the task
migrations/ directory,
then wire up versions and descriptions in the index file:
src/server/migrations/backfill-todo-status.ts
src/server/migrations/index.ts
src/server/app.ts
How Migrations Run
On application startup, Modelence will:- Acquire a distributed
migrationslock. If another instance already owns it, this instance skips running migrations. - Read existing migration versions from the
_modelenceMigrationscollection. - Run only pending migration versions from your
migrationsarray. - Write a record to
_modelenceMigrationswith:versionstatus(completedorfailed)descriptionoutput(handler result or error message)appliedAt
- Release the lock.
Migrations run in the order they appear in your
migrations array, so keep
that array intentionally ordered and use unique versions.Store indexes run before migrations with this startup behavior:
- Stores using
indexCreationMode: 'blocking'are awaited before migrations begin. Use this for small collections with critical index dependencies (e.g. unique indexes that a migration relies on). - Stores using
indexCreationMode: 'background'may still be creating indexes while migrations run. Prefer this for large collections to avoid blocking app startup.
Migrations and Cron Jobs
Recommended approach:- Make migration handlers idempotent (safe to run once or be retried manually).
- Use conditional updates (for example, update only documents missing the new field).
- Keep cron handlers compatible with both pre-migration and post-migration data during rollout windows.
- If a cron job strictly depends on a migration, add an explicit readiness guard in the cron handler.
Failure Behavior
Failed migrations are recorded withstatus: 'failed'. Since version tracking
is version-based, a failed version is still considered already seen on future
starts — it will not be retried automatically on the next boot.
If you need to rerun logic, prefer creating a new migration version. Edit a
previous version’s handler only if the migration has never run successfully in
any environment.
No Built-in Rollback
Modelence migrations are forward-only. There is nodown handler, no
auto-revert on failure, and no CLI command to roll back. Failed handlers do
not un-do partial writes — design each handler to be idempotent so a rerun
(after manual cleanup) converges on the desired state.
Practical guidance:
- Use conditional updates (e.g.
{ field: { $exists: false } }) so partial progress is safe to resume. - Avoid destructive operations (drops, deletes) inside the same migration that performs the new write. Split them into separate versions and only run the destructive step after verifying the prior version succeeded everywhere.
- Wrap multi-document changes in your own checkpoint logic if you need to resume after a crash mid-handler — the runner itself records only the final outcome per version.
Manual Cleanup of _modelenceMigrations
To force a version to rerun, delete (or update) its document in the
_modelenceMigrations collection before restarting the app. Each document has
the shape:
version: 7 migration:
CLI Surface
Migrations are run only at application startup. There is currently nomodelence migrate CLI command, no dry-run mode, and no way to invoke a
single migration handler out-of-band. To run or re-run migrations you must
(re)start the app — typically by deploying a new version that includes the
new entries in your migrations array.