Expand-and-Contract Migrations
Your ASP.NET Core API deploys gradually across several instances, and a release adds a new required column, marked NOT NULL, in the same migration that ships the code using it.
For the few minutes the rollout takes, some instances already run the new code and some still run the old code. The old instances have never even heard of the new column, so every insert they run fails, because the database now demands a value they don't know to provide.
A schema change and the code that depends on it, rolled out together, break whichever version isn't caught up yet. That's exactly what expand-and-contract migrations avoid.
Splitting the migration in two is the fix: expand first, add the new column as nullable, or with a default, in its own migration, deployed before any code depends on it. Ship the code that starts populating it and backfill existing rows while old and new code both keep running without errors, then contract: only once every instance is on the new code and every row has a value, add the NOT NULL constraint in a later, separate migration.
Use: EF Core Migrations (dotnet ef migrations add)
Split a breaking schema change into two migrations: widen first, tighten only after everything has caught up.
A city widens a road by building the new lane alongside the old one first, and only closes the old lane once the new one is open and traffic has moved over.
Closing the old lane before the new one exists leaves every car with nowhere to go.
Widen first, and narrow only once everything has safely moved to the new lane.