SQLx includes a first-class migration system that tracks and applies versioned SQL scripts to keep your database schema in sync with your application code. Migrations are plain SQL files stored alongside your source code, and SQLx records which ones have been applied in aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/launchbadge/sqlx/llms.txt
Use this file to discover all available pages before exploring further.
_sqlx_migrations table so that only pending scripts are ever executed.
How SQLx migrations work
Every migration is a.sql file with a numeric version prefix. When you run migrations, SQLx reads the _sqlx_migrations table, compares it against the files in your migrations directory, and applies only the scripts that have not yet been recorded. Each applied migration is stored with a SHA-384 checksum; if a previously-applied file changes on disk, SQLx returns an error to prevent silent schema divergence.
Migrations require the
migrate feature flag. Add it to your Cargo.toml alongside the relevant database feature:Migration directory structure
By convention, migration files live in amigrations/ directory at the root of your project. SQLx uses the filename to determine version order and description. Files that do not match the expected format are silently ignored.
<VERSION>_<DESCRIPTION>.sql, where <VERSION> is any integer greater than zero. The sqlx migrate add command generates timestamps in YYYYMMDDHHmmss format automatically. For reversible migrations, files come in .up.sql / .down.sql pairs:
The migrate! macro
The migrate! macro embeds your migration files directly into the compiled binary at build time. This is the most common way to run migrations in production because it does not require the migrations/ directory to be present at runtime.
CARGO_MANIFEST_DIR (the directory containing Cargo.toml) at compile time.
Programmatic migration with Migrator
For cases where you need runtime control — such as loading migrations from a path determined at startup — use Migrator::new():
Migrator exposes additional configuration methods:
| Method | Description |
|---|---|
set_ignore_missing(true) | Ignore applied migrations that are no longer present on disk |
set_locking(false) | Disable advisory locking (e.g. for CockroachDB) |
dangerous_set_table_name(name) | Override the _sqlx_migrations tracking table name |
The _sqlx_migrations table
SQLx creates this table automatically on the first migration run. It records the version number, description, type, checksum, and execution timestamp for each applied migration. You should not manually modify this table.
| Column | Type | Description |
|---|---|---|
version | BIGINT | The numeric version from the filename |
description | TEXT | The human-readable name from the filename |
installed_on | TIMESTAMPTZ | When the migration was applied |
success | BOOLEAN | Whether the migration completed without error |
checksum | BYTEA | SHA-384 hash of the migration SQL |
execution_time | BIGINT | Duration in nanoseconds |
The migrate feature flag
The migration system is gated behind the migrate Cargo feature. Without it, neither sqlx::migrate!() nor sqlx::migrate::Migrator will be available.
Writing migrations
Create migration files with the CLI, run and revert them, and check status.
Offline mode
Cache query metadata so you can build without a live database in CI.