A new release expects a renamed database column. During deployment, an older worker still uses the original name. Renaming the column in one step can break that worker even if the new application passes its own tests.
The expand-and-contract pattern described in Prisma’s documentation separates adding a replacement structure from removing the old one. The general principle is compatibility during transition; the exact migration commands and transaction behaviour depend on the database and tooling.
List every reader and writer
Include web servers, background jobs, scheduled tasks, reporting tools and older mobile clients where relevant. A deployment is not complete merely because the main web process has restarted. Decide which versions must coexist and how long queued work can continue using the old shape.
Use an explicit transition
- Expand: add the new structure in a way that existing code can tolerate.
- Migrate: populate and verify the new data, accounting for writes that occur during the transition.
- Switch: deploy readers and writers that use the new structure and observe their behaviour.
- Contract: remove the obsolete structure only after its users are gone.
Suppose a boolean is becoming a richer status field. Define how each existing value maps to the new states and what happens to new writes during the backfill. “Copy the column” is not enough if the application can change rows at the same time.
Test the awkward combinations
Test old application code against the expanded schema and new code against partially migrated data where that state is possible. Check job retries, failure recovery and the cost of large updates. A migration that works on ten rows may lock or overload a production-sized table.
Plan recovery before deployment. Rolling back application code does not automatically reverse a destructive data change. Keep each stage observable and define what evidence permits the next stage. Compatibility is a property of the whole transition, not just of the final schema.

