Adding a new column to a database table seems trivial. It isn’t. Every change carries risk: downtime, lock contention, broken queries, stale caches, data drift. The more traffic your system handles, the smaller the window you have for safety.
Choosing the right approach starts with understanding schema evolution in your stack. For OLTP databases like PostgreSQL or MySQL, creating a new column is instant if it has no default value and is nullable. Adding one with a non-null default can cause a table rewrite, locking reads and writes until it finishes. On large datasets, this can stop production cold.
Best practice:
- Deploy the migration in phases.
- Add the new column as nullable and without a default.
- Backfill data in small batches.
- Add constraints or defaults only after the backfill completes.
For distributed systems, also update your application code to handle both old and new schemas during the transition. In microservices, this means making each service tolerant to missing fields until the rollout is complete. Backwards compatibility is not optional.