For production, prefer a controlled migration step in your deployment process over running schema changes whenever an application container starts. Instances can restart or scale independently of a release.
With container deployments on Vercel, plan database changes separately from serving HTTP traffic, including which environment the migration may modify.
Startup migrations can be acceptable in a controlled setting. The issue is whether startup supplies the coordination and failure handling that a production database change requires.
Copy link to headingWhy is container startup the wrong default trigger?
Starting a process and releasing a schema change happen for different reasons. A new application version may need a new table. Starting another replica of the existing version should not create a second, independent opportunity to alter the schema.
Consider a hypothetical deployment that adds several API instances. If each startup attempts the same migration, your migration tool needs to coordinate them. Even when the tool prevents duplicate execution, application startup now waits on deployment work. A migration error can stop instances from becoming ready.
Microsoft's EF Core migration guidance describes runtime migration tradeoffs and provides separate deployment artifacts. It also recommends a deployment identity with schema permissions, while the running application normally uses the permissions needed for its ordinary data operations.
The architectural recommendation follows from those responsibilities: give database changes an explicit place in the release process and give application startup a readiness check.
Copy link to headingWhere should migration work happen instead?
Use a deployment runner that can reach the intended database and report whether the operation succeeded. It might be a CI job or a platform's documented release mechanism. Keep the migration tied to the application version being released, and coordinate access when multiple releases target the same database.
Package the migration as a versioned script or executable that your deployment runner can execute separately. Microsoft’s EF Core guidance recommends generating a migration bundle during the build and running it as a dedicated deployment job. Identify the artifact and target database explicitly, and stop the release if the migration fails.
This is a release design to implement with your toolchain, not a built-in sequence promised by every host. Decide what stops deployment if migration fails. A failure message in a log is insufficient if the next step releases incompatible code anyway.
Copy link to headingHow do you keep old and new application versions compatible?
Allow for more than one version of your application to exist during a release. An older process may still handle work when the new schema arrives. A rollback also brings older code back to a database that has already changed.
The parallel change pattern, also called expand and contract, separates adding compatibility from removing the old interface. A schema change can follow the same approach.
For example, suppose an account record needs a new display field. Add the field in a form that existing code tolerates. Release code that can populate it while preserving the old behavior. Backfill existing records and verify the result before switching readers. Remove the obsolete field only after the application versions that use it have left the supported release and rollback set.
The right constraints and locking behavior depend on the database. Review the generated change and test its effect on live traffic before applying it in production.
Copy link to headingHow should previews handle schema changes?
Give a preview migration an explicit database target. If two branches apply different schemas to the same preview database, one branch's successful deployment can make the other's application incompatible with its data environment.
Vercel's full-stack preview guide covers deploying related services together. Database isolation still needs its own design. Use a separate database or supported database branch when you need independently testable schema changes, and connect the preview to that resource through the appropriate configuration.
Check the migration runner's configuration as well as the web application's. A preview app pointing at a test database does not help if its deployment job receives production credentials. Confirm the target using a safe identifier, without printing connection secrets.
Copy link to headingWhat does application rollback leave behind?
Rolling back application code doesn't reverse a database operation by itself. If the release removed a column, starting an earlier image cannot restore its contents. Decide whether rollback means returning to compatible older code, applying a tested corrective migration, or recovering data through the database's recovery process.
Practice that decision on a disposable database with representative data. Apply the proposed migration, start the new application, then check the version you intend to keep as a rollback candidate. Record which schema each version can use.
Also rehearse a failed migration. Determine which changes committed and what the migration tool records before deciding whether to retry. A retry must follow the database and tool's documented recovery behavior; restarting application containers is not a recovery plan.
Copy link to headingWhen can startup migrations be acceptable?
A local development environment or disposable demonstration database can reasonably trade release controls for a shorter startup flow. Some applications also accept startup migrations with explicit coordination and tested failure behavior. Treat that as an operating decision, rather than an assumption inherited from a sample Dockerfile.
Container hosting doesn't automatically provide a database release hook. On Vercel, verify the migration runner and its database connectivity separately from the container-image HTTP deployment path. If the runner cannot reach the database, choose a suitable execution environment before attaching migration commands to the release.
Copy link to headingFrequently asked questions
Copy link to headingDoes a migration lock make startup migrations risk-free?
No. Coordinating concurrent migration attempts does not establish compatibility between the resulting schema and every running application version. Startup also remains dependent on migration success and completion.
Copy link to headingShould every replica apply the database migration?
Prefer one coordinated release process for each target database, with the migration tool tracking applied changes. Application replicas can then start against a compatible schema without each initiating release work.
Copy link to headingWill rolling back a container restore the previous database schema?
No. Replacing application code does not undo schema changes or restore deleted data. Plan the application's supported rollback versions alongside the database migration and recovery procedure.
Copy link to headingCan preview and production migrations use the same database?
Sharing a database gives preview migrations the ability to change production's schema. On Vercel, configure the preview and its migration runner for an isolated database when testing changes that must not affect production.