Skip to main content
PocketBase uses a migration system to track and apply database schema changes. Migrations ensure that database modifications are versioned, reproducible, and can be rolled back if needed.

Understanding migrations

PocketBase has two types of migrations:
  • System migrations: Built into PocketBase core, these handle framework schema updates
  • App migrations: User-defined migrations for your application’s collections and data
Migrations are stored in the _migrations table and executed in order based on their filename.

Migration file structure

Migrations can be written in JavaScript or Go:

JavaScript migrations

Located in pb_migrations/ by default:

Go migrations

Located in migrations/ by default:

Setting up migrations

Enable migrations in your PocketBase application:

Configuration options

  • TemplateLang: migratecmd.TemplateLangJS or migratecmd.TemplateLangGo (default: Go)
  • Automigrate: Enable automatic migration generation on collection changes (default: false)
  • Dir: Custom migrations directory (default: pb_migrations/ for JS, migrations/ for Go)

Creating migrations

Manual migration creation

Create a blank migration template:
This generates a file like 1234567890_add_user_bio.js:

Collections snapshot

Generate a migration with the current collections state:
This creates a migration like 1234567890_collections_snapshot.js:

Automigrations

When Automigrate: true is enabled, PocketBase automatically creates migrations when you modify collections through the admin UI. For example, creating a new collection generates:
Automigrations are prefixed with action names: created_, updated_, or deleted_.

Applying migrations

Apply all pending migrations

Output:

Migration execution process

From core/migrations_runner.go:122-173, the Up() method:
1

Initialize migrations table

Creates the _migrations table if it doesn’t exist.
2

Check applied status

Queries the _migrations table to see if each migration has been applied.
3

Execute in transaction

Runs unapplied migrations within a database transaction for safety.
4

Record migration

Saves the migration record with timestamp to _migrations table.
Migrations run in both the main database and auxiliary database transactions. Any error will rollback all changes.

Reverting migrations

Revert last migration

This prompts for confirmation:

Revert multiple migrations

Reverts the last 3 migrations.

Revert all migrations

Reverting migrations can cause data loss if the down function drops collections or fields. Always back up before reverting.

Migration best practices

Always implement both up and down functions:
Good migration names describe the change:
  • add_user_bio_field.js
  • create_comments_collection.js
  • migrate_old_posts_to_new_schema.js
  • migration1.js
  • update.js
Before applying to production:
  1. Create migration in development
  2. Test migrate up
  3. Verify application functionality
  4. Test migrate down
  5. Test migrate up again
  6. Commit migration file
  7. Deploy to production
Create separate migrations for different changes:
When migrating data, handle edge cases:

Advanced migration techniques

Conditional migrations with ReapplyCondition

From core/migrations_list.go:9-14, migrations support conditional reapplication:
Use case: Reapply a migration when certain conditions change:

Programmatic migration execution

Run migrations from Go code:

Custom migrations table

Change the default migrations table name:

Migration hooks

You can hook into migration events, though this is typically done through the migration files themselves. The migration system triggers events during execution:

Troubleshooting

Migration already applied

Issue: Migration shows as applied but changes aren’t visible. Solution: Check the _migrations table:
Remove the entry to reapply:
Then run migrate up again.

Migration file not found

Issue: _migrations table references files that don’t exist. Solution: Sync the migrations table:
This removes references to deleted migration files.

Transaction deadlock

Issue: Migration times out or deadlocks. Solution:
  • Ensure migrations don’t have long-running operations
  • Split large data migrations into smaller batches
  • Avoid external API calls in migrations

Import errors in Go migrations

Issue: undefined: Collection or similar errors. Solution: Import the correct packages:

Next steps

Going to production

Learn production deployment best practices

Backups

Set up automated backups for your data