The Command#
zonai db migrate apply
Alias: up
Applies all pending (not-yet-applied) migrations in timestamp order. Safe to run multiple times — already-applied migrations are recorded in the
_migrations table and skipped.
Auto-Apply at Server Start#
zonai serve applies pending migrations automatically before opening the HTTP listener. In most workflows — dev and production alike — you don't need to run
apply manually.
Startup order:
- Compile workers (dev mode only)
- Apply pending migrations
- Ping workers
- Accept requests
Disabling Auto-Apply#
zonai serve --no-auto-migrate
Starts the server without applying any migrations. Useful when you want to manually review and control migrations in production:
# Review migrations first
zonai db migrate apply --dry-run # (if supported, or inspect .sql files directly)
# Apply after review
zonai db migrate apply
# Then start the server
./zonai serve --release
What Happens During Apply#
Each migration file runs inside a SQLite transaction:
-
On success: the migration filename is recorded in
_migrations, the transaction commits, and Zonai moves to the next file. - On failure: the transaction rolls back. The migration is NOT recorded. The server reports the error and does not start.
Migrations run one at a time, in order. A failure stops the process at that file — later migrations do not run.
Checking Migration Status#
The _migrations table in the SQLite database records every applied migration:
SELECT * FROM _migrations ORDER BY applied_at;
Server startup logs also print the names of any pending migrations before applying them.
