LogoZonai

Migrations Overview

How Zonai tracks and applies schema changes to the database.

A migration is a SQL file that transforms the database from one schema version to the next. Migrations are the source of truth for what the database looks like — the SQLite file is derived from running them in order.

Migration files live in .zonai/migrations/ (configurable via migrationsPath in zonai.yaml). Commit these files to version control.

Schema changes do not remove streaming — every table keeps /db/stream* automatically. Client guide: Streaming.

Migration File Naming#

<unix_timestamp>_<optional_name>.sql

Examples:

1720000000.sql
1720005000_add_avatar_column.sql
1720010000_add_blog_posts_table.sql

The timestamp determines the application order. The optional name comes from --name when generating.

The Internal Tracking Table#

Zonai maintains a _migrations table in the database. Each applied migration is recorded with its filename and timestamp. On startup, Zonai checks this table to determine which migrations are pending.

You Don't Write Migrations by Hand#

Migrations are generated by diffing your current schema definitions against snapshots of the schemas:

zonai db migrate generate --name add_avatar_column

Zonai compares what the schema says should exist against what is in the database and generates the appropriate SQL. You review it, not write it.

See Generating Migrations.

Auto-Apply on Server Start#

zonai serve applies all pending migrations before opening the HTTP listener:

  1. Compile workers
  2. Apply pending migrations
  3. Ping workers
  4. Accept HTTP connections

A failed migration prevents the server from starting. This is by design — an inconsistent schema is worse than a delayed start.

  1. Edit a schema file (add a column, add a table, etc.)
  2. Run zonai db migrate generate (or press m in dev mode)
  3. Review the generated .sql file
  4. The server auto-applies it on next start, or apply manually: zonai db migrate apply