Database Migrations
The Enterprise Stack includes a MongoDB migration system that keeps the database structure, indexes, and stored data in sync with the version of the Enterprise API you are running.
Migrations are executed automatically when the Enterprise API starts. They can also be inspected and scheduled manually through the global administration API.
Database migrations are currently supported for MongoDB deployments. The in-memory database does not support migration execution.
How Migrations Work
Each migration has a numeric version, a description, a list of affected collections, and a set of allowed actions. Migrations are registered in version order and are designed to be safe to run in clustered deployments.
When an Enterprise API node starts:
- The node connects to MongoDB.
- The migration framework checks the current cluster database version.
- Required startup migrations are executed before the application continues.
- Background migrations are started asynchronously after startup.
- The node records progress and results in the
migrationscollection.
Only one node executes migrations at a time. The migration system uses a MongoDB-backed lock named migration_lock in the
cluster_locks collection. Other nodes wait until the lock is released or expires.
Migration Types
Migrations are grouped by impact:
SCHEMA- creates or updates collections and document structure.INDEX- creates, updates, or drops database indexes.DATA- transforms existing records. These migrations can take longer on large collections.
Automatic Startup Behavior
Most migrations are applied automatically. The Enterprise API distinguishes between two execution modes:
- Startup migrations run before the application completes database initialization.
- Background migrations run after startup, so the API can become available while lower-risk migrations continue.
Background migrations are used when the application can safely handle both the old and new data shape during the migration.
Before upgrading production environments, create a database backup and review the release notes for migrations introduced by the target version.
Cluster Safety and Recovery
The migration framework is cluster-aware:
- Only one node can hold the migration lock and execute migrations.
- Lock ownership is refreshed while a migration is running.
- If a node stops while holding the lock, the lock expires and another node can continue.
- Migration runs without a
completedAttimestamp are treated as aborted and can be recovered. - If a node with an older database version leaves the cluster, the missing migrations are scheduled for execution.
This allows rolling deployments while preventing two nodes from applying the same migration at the same time.
Get Migration Status
Use the migration status endpoint to list registered migrations and their run history.
Endpoint: /v1/admin/admin/migrations
Example Request
curl -X 'GET' \
'https://{host}/v1/admin/admin/migrations' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {superAdminToken}'
Example Response
[
{
"version": 4,
"allowedActions": [
"APPLY",
"RUN",
"DRY_RUN",
"VALIDATE_PRECONDITIONS"
],
"description": "Migrate 'timestamp' (millis from epoch) field to 'created_at' and 'updated_at' (string ISO date)",
"affectsCollections": [
"organization_trees"
],
"runs": [
{
"runId": "1a5a4a42-2a3f-48df-a571-8a4b68c9a941",
"action": "APPLY",
"remark": "Startup of Application",
"startedAt": "2026-06-25T09:15:00.000Z",
"completedAt": "2026-06-25T09:15:03.000Z",
"totalItems": 1200,
"processedItems": 1200,
"success": true,
"messages": [],
"errorMessage": null
}
]
}
]
Response Fields
version: Numeric migration version.allowedActions: Actions that can be scheduled for this migration.description: Human-readable summary of what the migration does.affectsCollections: MongoDB collections touched by the migration.runs: Previous or currently running migration attempts.runId: Unique identifier for one migration run.startedAt: Time when execution started. If this is empty, the action is scheduled but not yet started.completedAt: Time when execution finished. If this is empty afterstartedAtis set, the run is still active or was interrupted.totalItemsandprocessedItems: Progress counters for migrations that report item-level progress.success:truefor successful runs,falsefor failed runs, and empty while the run is still pending or active.messages: Informational messages written by the migration.errorMessage: Error details for failed runs.
Schedule a Migration Action
Migration actions are scheduled through the administration API. The endpoint returns 202 Accepted after the action has
been recorded. Execution starts once a node acquires the database migration lock.
Endpoint: /v1/admin/admin/migrations/{dbVersion}
Example Request
curl -X 'POST' \
'https://{host}/v1/admin/admin/migrations/{dbVersion}' \
-H 'accept: */*' \
-H 'Authorization: Bearer {superAdminToken}' \
-H 'Content-Type: application/json' \
-d '{
"action": "DRY_RUN",
"remark": "Check migration impact before production upgrade"
}'
Path Parameters
dbVersion: Version of the migration to schedule, for example4.
Body Parameters
action: Migration action to schedule.remark: Optional note stored with the migration run history.
Response
202 Accepted- The migration action was scheduled.
Migration Actions
The following actions can appear in allowedActions:
APPLY: Applies the migration and updates the cluster database version after success. This is the normal automatic startup/background action.RUN: Executes the migration logic without updating the cluster database version.DRY_RUN: Executes the migration's dry-run logic where supported. Use it to inspect impact before applying a migration.VALIDATE_PRECONDITIONS: Runs precondition checks and records messages or errors without applying the migration.ROLLBACK: Runs the rollback logic where supported. Not every migration supports rollback.
Only schedule actions listed in allowedActions for the migration. Unsupported actions are rejected by the API.
Dry Run and Rollback Support
Dry run and rollback support is defined per migration. Always check the allowedActions field returned by
GET /v1/admin/admin/migrations before scheduling either action.
Dry Run
DRY_RUN is used to preview the impact of a migration without applying persistent changes. A dry run still creates a
migration run history entry, so you can inspect messages, totalItems, processedItems, success, and errorMessage
after it finishes.
Use dry runs when you want to:
- Check that migration preconditions pass.
- Estimate how many records are affected.
- Review informational messages before applying a data migration.
Endpoint: /v1/admin/admin/migrations/{dbVersion}
Example Request
curl -X 'POST' \
'https://{host}/v1/admin/admin/migrations/{dbVersion}' \
-H 'accept: */*' \
-H 'Authorization: Bearer {superAdminToken}' \
-H 'Content-Type: application/json' \
-d '{
"action": "DRY_RUN",
"remark": "Preview migration impact before applying it"
}'
Rollback
ROLLBACK executes a migration's rollback logic where that migration supports it. Rollbacks do not update the cluster
database version. They are intended for targeted operational recovery, not as a replacement for a database backup.
Not every migration can be rolled back. Data transformations may not have enough information to reconstruct the previous
state. For production upgrades, always keep a MongoDB backup even if a migration lists ROLLBACK in allowedActions.
Endpoint: /v1/admin/admin/migrations/{dbVersion}
Example Request
curl -X 'POST' \
'https://{host}/v1/admin/admin/migrations/{dbVersion}' \
-H 'accept: */*' \
-H 'Authorization: Bearer {superAdminToken}' \
-H 'Content-Type: application/json' \
-d '{
"action": "ROLLBACK",
"remark": "Rollback migration after operational validation"
}'
Common Operational Flow
For a production upgrade:
- Back up the MongoDB database.
- Deploy the new Enterprise API version.
- Watch the application logs for migration progress.
- Call
GET /v1/admin/admin/migrationsto verify each required migration hassuccess: true. - Investigate any run with
success: falseor anerrorMessage.
For a manual check before applying a specific migration:
- Call
GET /v1/admin/admin/migrationsand find the migration version. - Schedule
VALIDATE_PRECONDITIONSif it is listed inallowedActions. - Schedule
DRY_RUNif it is listed inallowedActions. - Review the
runsentry for messages, progress, and errors. - Schedule
APPLYonly when you are ready to execute the migration.
Current Migration Coverage
The Enterprise API currently registers migrations for:
- Initial MongoDB collection creation. This migration supports
DRY_RUN. - Base indexes for
organization_trees,host_aliases, andaccounts. - Extended indexes for
organization_trees. - Event collection indexes.
- Migration of legacy
timestampfields tocreatedAtandupdatedAtonorganization_trees. This migration supportsDRY_RUN. - An
updatedAtindex for sorting and queryingorganization_trees. This migration supportsROLLBACK.
New Enterprise API releases may add more migrations. Always use the status endpoint as the source of truth for the migrations available in your running version.
Troubleshooting
Migration Is Waiting
If a migration is scheduled but has no startedAt, another node may currently hold the migration lock. The scheduled run
will start when a node acquires the lock.
Migration Was Interrupted
If a migration has startedAt but no completedAt, the node may have stopped before finishing. The framework treats this
as an aborted run and will attempt recovery on startup or when a migration recovery job is triggered.
Migration Failed
If success is false, check errorMessage and the application logs for the root cause. After resolving the issue, you
can schedule the same supported action again.
No Migrations Are Listed
If the status endpoint returns an empty list, verify that the deployment is using MongoDB as its database. Migration execution is not supported for the in-memory database.
