# Workflow: D1 schema evolution

## 1. Write the migration

Create a versioned `.sql` file in the migrations directory. Files apply in filename order: review the sequence, because a misnumbered file runs at the wrong time. Keep migrations SQLite-compatible: D1 does not run Postgres or MySQL dialect features.

## 2. Apply locally

Run `wrangler d1 migrations apply DB --local`. Exercise the new schema through the app locally: queries, writes, edge cases. Local failures are cheap.

## 3. Apply to remote deliberately

Apply with the database name (not the binding name): bindings can change between environments, the database name cannot, so the name protects you from migrating the wrong database. Check the `d1_migrations` table on the remote database before and after to confirm state.

## 4. Coordinate with code

Deploy the migration before the code that needs it (expand), then deploy code that uses the new schema, then later remove the old schema usage (contract). For breaking changes, the migration and the code deploy are two separate steps with verification between.

## 5. ORM layouts

If Drizzle (or similar) writes each migration as its own subdirectory, set `migrations_pattern` to the matching glob or the migrations are silently undiscovered.

## Checklist

- Local apply, test, remote apply. Never the reverse.
- Database name for apply commands.
- Verify d1_migrations state on the remote DB after every production migration.