Overview
Migrations in Directus are TypeScript files that define database changes. Each migration has:- Version - A unique identifier (timestamp-based)
- Name - Descriptive name of the migration
- Up Function - Code to apply the migration
- Down Function - Code to revert the migration
directus_migrations table.
Migration Structure
A basic migration file follows this pattern:System Migrations
Directus includes built-in migrations located in/api/src/database/migrations/. These handle:
- Creating system tables (users, files, collections, etc.)
- Adding new features to Directus
- Modifying system table structures
- Data transformations for upgrades
Migration Naming Convention
System migrations follow the pattern:20260204A-add-deployment.ts20260128A-add-collaborative-editing.ts20251103A-add-ai-settings.ts
YYYYMMDD{A-Z} where:
YYYYMMDD- Date of the migration{A-Z}- Letter suffix for multiple migrations on the same day
Custom Migrations
You can create custom migrations to manage your own schema changes.Location
Custom migrations are stored in:Creating a Custom Migration
- Create a new file in your migrations directory:
- Define the up and down functions:
Custom Migration Format
Custom migrations must:- Have a name containing a dash (
-) - Use
.js,.cjs, or.mjsextension - Export
upanddownfunctions - Use valid JavaScript/CommonJS/ESM syntax
Running Migrations
CLI Commands
Run migrations using the Directus CLI:Programmatic Usage
Run migrations programmatically:Migration Execution Order
Migrations execute in version order:- System migrations (sorted by version)
- Custom migrations (sorted by version)
- Combined and deduplicated by version
Migration Examples
Creating Tables
Adding Columns
Modifying Columns
Creating Indexes
Data Migrations
Foreign Key Relationships
Migration Tracking
Thedirectus_migrations table tracks applied migrations:
| Column | Type | Description |
|---|---|---|
version | string | Migration version identifier |
name | string | Human-readable migration name |
timestamp | datetime | When the migration was applied |
Validation
Migration Validation
Directus validates migrations on startup:Version Collision Detection
Migrations must have unique versions:Best Practices
Always Provide Down Migrations
Even if you don’t plan to rollback, always implement thedown function:
Test Both Directions
Test that migrations can be applied and reverted:Keep Migrations Small
Create focused migrations that do one thing well:Use Transactions
Knex migrations run in transactions by default (except MySQL DDL):Handle Database Differences
Account for database-specific behaviors:Document Complex Migrations
Add comments for complex logic:Avoid Direct Table References
Use the schema builder instead of raw SQL when possible:Backup Before Migrations
Always backup your database before running migrations in production:Troubleshooting
Migration Failed Mid-Execution
If a migration fails partway through:- Check the
directus_migrationstable - If the migration wasn’t recorded, fix the issue and run again
- If it was recorded but incomplete, manually revert changes and remove the record
Version Collision Error
Missing Migration File
If a migration is recorded in the database but the file is missing, you can:- Restore the migration file from version control
- Or remove the record (risky - only if you’re certain):
Next Steps
- Explore Schema Management
- Learn about Supported Databases
- Check the Knex.js Schema Builder Documentation