The Database Migration Trap: How AI Assistants Break Production | Deployxa

AI assistants generate migrations that work in development but break in production. Here are the 6 reasons and the production checklist to fix them.

← Back to Dispatch Articles
Engineering Log

The Database Migration Trap: How AI Assistants Break Production

AI assistants generate migrations that work in development but break in production. Here are the 6 reasons and the production checklist to fix them.

The Database Migration Trap

You asked Cursor to add a new column to your database. It generated a migration, you ran it, and it worked in development. You deployed to production, and the migration ran, but it locked the users table for 5 minutes, which caused all requests to time out, and your app was down for 5 minutes. Or worse, the migration deleted a column that was still in use, and you lost data. This is the database migration trap, and it is one of the most dangerous failures in AI-generated apps. AI assistants generate migrations that work in development (with small data sets) but break in production (with large data sets and concurrent requests). Here are the 6 reasons AI-generated database migrations break production, and the production checklist to fix them.

The direct answer is that database migrations are changes to your database schema (e.g., adding a column, creating an index, renaming a table), and they are one of the most dangerous operations in production, because they can lock tables, lose data, and cause downtime. AI assistants generate migrations that work in development but break in production, because they do not consider the production constraints (large data sets, concurrent requests, locking). The 6 reasons are: no rollback strategy, no testing, table locking, data loss, no zero-downtime strategy, and no migration ordering. Each one has a known cause and a known fix, and applying all 6 fixes gives you a production-ready migration strategy. For more on production safety, see our article on the 14-point readiness engine.

Reason 1: No Rollback Strategy

The most common reason AI-generated migrations break production is the lack of a rollback strategy. AI assistants generate "up" migrations (which apply the change) but rarely generate "down" migrations (which revert the change). If a migration causes an issue in production, you cannot roll it back, which means you are stuck with the change. The fix is to always generate a "down" migration alongside the "up" migration, and to test the rollback in staging before deploying to production. For Prisma, migrations are not reversible by default, so you need to manually create a rollback migration. For Rails, migrations are reversible by default (via def down). For more on rollback strategies, see our article on Traefik v3 dynamic routing.

Reason 2: No Testing

The second reason is no testing. AI assistants generate migrations that are not tested, which means they might contain errors (e.g., a syntax error, a constraint violation) that only surface in production. The fix is to test migrations in staging (which has a copy of the production data) before deploying to production. Run the migration in staging, verify the app works, and then deploy to production.

Reason 3: Table Locking

The third reason is table locking. Some migrations (e.g., adding a column with a default value, creating an index) lock the table for the duration of the migration, which means concurrent requests are blocked. For small tables, the lock is brief, but for large tables (millions of rows), the lock can last minutes, which causes downtime. AI assistants do not consider table locking, because it is not an issue in development (with small data sets). The fix is to use zero-downtime migration strategies: for adding a column, add it without a default value (which does not lock the table), then backfill the default value in batches; for creating an index, use CREATE INDEX CONCURRENTLY (Postgres), which does not lock the table. For more on database performance, see our article on database connection pooling across blue/green deployments.

Reason 4: Data Loss

The fourth reason is data loss. Some migrations (e.g., dropping a column, renaming a column) can lose data if not done carefully. AI assistants generate migrations that drop or rename columns directly, which loses the data in those columns. The fix is to use a multi-step migration strategy: first, add the new column (without dropping the old one); second, backfill the new column from the old one; third, update the app to use the new column; fourth, drop the old column (after verifying the app works). This strategy ensures no data is lost, even if something goes wrong.

Reason 5: No Zero-Downtime Strategy

The fifth reason is no zero-downtime strategy. Some migrations require downtime (e.g., changing a column type, adding a NOT NULL constraint to an existing column). AI assistants do not consider this, which means the migration causes downtime in production. The fix is to use a multi-step migration strategy that avoids downtime: for changing a column type, add a new column with the new type, backfill it from the old column, update the app, and drop the old column; for adding a NOT NULL constraint, add the column as nullable, backfill the values, and then add the constraint.

Reason 6: No Migration Ordering

The sixth reason is no migration ordering. Migrations need to be applied in order (e.g., migration 2 depends on migration 1), and if the order is wrong, the migration fails. AI assistants generate migrations without considering the order, which can cause failures. The fix is to use a migration tool (e.g., Prisma Migrate, Rails Migrations, Alembic) that tracks the migration order and applies them in sequence. For more on migration tools, see our article on fixing DATABASE_URL not set.

Step-by-Step: A Safe Migration Strategy

Here is a safe migration strategy for adding a NOT NULL column to a large table.

Step 1: Add the column as nullable

-- Migration 1: Add the column as nullable (does not lock the table)
ALTER TABLE users ADD COLUMN email_verified BOOLEAN;

Step 2: Backfill the values

-- Migration 2: Backfill the values in batches (does not lock the table)
-- Run this in a script, not a migration, to avoid long-running transactions
UPDATE users SET email_verified = false WHERE email_verified IS NULL LIMIT 1000;
-- Repeat until all rows are backfilled

Step 3: Add the NOT NULL constraint

-- Migration 3: Add the NOT NULL constraint (locks the table briefly, but all rows are already populated)
ALTER TABLE users ALTER COLUMN email_verified SET NOT NULL;

Step 4: Update the app

Update the app to use the new column. Deploy the updated app.

Step 5: Verify with deployxa doctor

Run deployxa doctor to verify your app's health. The 14-point readiness engine checks SSL, DNS, environment variables, health endpoints, and container status.

Common Pitfalls and Troubleshooting

The first pitfall is running migrations during peak traffic. Migrations that lock tables should be run during off-peak hours (e.g., 3 AM), to minimize the impact. The fix is to schedule migrations during off-peak hours. The second pitfall is not backing up the database before migrating. If a migration goes wrong, you need a backup to restore from. The fix is to always back up the database before running a migration. The third pitfall is not monitoring the migration. A migration that takes too long might indicate a problem (e.g., a lock contention, a slow query). The fix is to monitor the migration's progress and to abort if it takes too long. The fourth pitfall is not having a rollback plan. If a migration causes an issue, you need to be able to roll it back quickly. The fix is to always have a rollback migration ready and to test it in staging. The fifth pitfall is not communicating with the team. Migrations can affect multiple team members (e.g., the on-call engineer, the product manager), which means you need to communicate the migration plan in advance. The fix is to announce migrations in advance (e.g., in a Slack channel) and to have a rollback plan documented.

Conclusion: Migrate Safely or Don't Migrate at All

The database migration trap is not a sign that your AI assistant did a bad job. It is a sign that database migrations are dangerous, and AI assistants do not consider the production constraints. By applying the 6 fixes above (rollback strategy, testing, avoid table locking, avoid data loss, zero-downtime strategy, migration ordering), you can migrate safely without breaking production. Stop running dangerous migrations and start migrating safely.

Ready to migrate safely? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on AI coding patterns, see our articles on the monitoring gap and the logging gap. Learn about the API versioning gap and the secrets management gap in our companion articles. Explore our free developer tools to speed up your workflow.

Ready to deploy with Deployxa?

Deploy your apps globally with automatic SSL and AI diagnostics.

Start Free Now