Migration Skill
This skill defines how to plan and execute migrations — database schema changes, data transformations, system upgrades, and platform moves. Migrations are the highest-risk operations in software delivery.
Migration Mindset
- Migrations are not features. They have their own lifecycle and risks. Never mix migration code with application code in the same deploy.
- Reversibility is mandatory. Every
upmust have adown. If you can't undo it, you're not ready to do it. - Test on realistic data. An empty database is not a test.
- Communicate risk. Every migration has a blast radius. Make it explicit.
Migration Types
| Type | Examples | Risk Level |
|---|---|---|
| Schema | Add column, create table, add index | Medium |
| Data | Backfill values, transform formats | High |
| Platform | Change hosting, switch databases | Very High |
| Dependency | Major version upgrade | Medium-High |
Migration Protocol
Step 1: Plan
- Document what changes and why
- Identify all affected systems, tables, and services
- Estimate duration, define rollback strategy
Step 2: Write Migration
Naming: {YYYYMMDD}_{sequence}_{description}.{direction}.sql
- Each migration is atomic
- Separate schema changes from data changes
- Never modify an already-applied migration
Step 3: Test
- Test on empty database (syntax)
- Test on seed data (existing data)
- Test on production-shaped data (realistic volume)
- Test the rollback
- Test the application with both old and new schema
Step 4: Execute
- Backup the database
- Deploy to staging first
- Deploy to production during low-traffic window
- Monitor for errors
- Verify data integrity
Step 5: Verify
- Migration applied successfully
- Data integrity checks pass
- Application functions correctly
- Rollback tested and verified
- Performance acceptable
Safe Schema Change Patterns
Adding a Column: Add as nullable → deploy writes → backfill → add constraint
Removing a Column: Stop reading → stop writing → drop column
Renaming a Column: Add new → write both → backfill → read new → write new → drop old
Adding an Index: Use CREATE INDEX CONCURRENTLY for large tables
Data Migration Rules
- Batch large operations (1,000-10,000 rows per batch)
- Log progress for long-running migrations
- Validate before and after (counts, distributions, foreign keys)
- Never delete data permanently in a migration — soft-delete first
Anti-Patterns
| Anti-Pattern | Do This Instead |
|---|---|
| Migration + feature in same deploy | Deploy separately |
No down migration |
Always write reversible migrations |
| Testing on empty database only | Test on production-shaped data |
| Editing applied migrations | Write new migration instead |
| No backup before migration | Always backup first |