mops migrate
Manage enhanced migration chains.
Migration files define how canister state transforms from one version to the next. They let you batch multiple incompatible stable state changes and deploy them together in a single upgrade. Each migration is a Motoko module with a migration function that takes the old state shape and returns the new one.
mops migrate new
mops migrate new <Name> [canister]
Create a new migration file in the next directory configured by [canisters.<name>.migrations].next.
<Name>— descriptive name for the migration (e.g.AddEmail,RemoveCounter)[canister]— canister name. Auto-detected if exactly one canister has[migrations]configured
The file is created with a timestamp prefix for correct ordering: YYYYMMDD_HHMMSS_<Name>.mo.
Examples
mops migrate new AddEmail
mops migrate new RemoveCounter backend
mops migrate freeze
mops migrate freeze [canister]
Move the migration file from the next directory into the chain directory, making it part of the permanent migration chain.
[canister]— canister name. Auto-detected if exactly one canister has[migrations]configured
Call freeze after verifying the migration with mops check and mops build. Once frozen, the migration becomes part of the permanent chain.
Example
mops migrate freeze
Configuration
Migrations are configured per-canister in mops.toml:
[canisters.backend.migrations]
chain = "migrations"
next = "next-migration"
check-limit = 1
build-limit = 100
See mops.toml reference for all fields.
Typical workflow
- Make a breaking change to your canister's stable state
- Run
mops check— the stable compatibility check fails, with a hint to create a migration - Run
mops migrate new AddEmail— creates a migration file innext-migration/ - Edit the migration file to define the state transformation
- Run
mops check— verifies the migration makes the upgrade compatible - Run
mops build— builds the WASM with the migration included - Deploy the canister
- Run
mops migrate freeze— moves the migration into the permanent chain
Chain trimming
Large migration chains increase WASM size and compilation time. Use check-limit and build-limit to trim the chain:
check-limit— only the last N migrations are included duringmops checkandmops check-stable. Set to1for fastest type-checking.build-limit— only the last N migrations are included duringmops build. Set higher (e.g.100) so the deployed WASM can apply multiple pending migrations.
The limits count the full virtual chain (frozen + pending next migration). This means mops build produces identical results whether a migration is still pending or already frozen.
Already-applied migrations are skipped at runtime by the Motoko RTS, so trimming is safe. When trimming is active, M0254 warnings are automatically suppressed.