The migration was done. The build was green. Then the first user report landed: the table needed a new column.
Adding a new column in production is never just one line of SQL. It’s schema changes, data backfills, constraints, indexes, and release coordination. A careless alter can lock tables and stall writes. A slow migration can block deploys. Even a harmless default value can break downstream code if it triggers unexpected behavior.
The safest process starts with definition. Write your migration explicitly, naming the new column, its type, nullability, and any defaults. Avoid implicit type conversions. In high-traffic systems, phase the change:
- Add the new column as nullable.
- Deploy code that writes to the new column alongside the old.
- Backfill data in controlled batches.
- Make the column required only after the system is stable.
Post-deploy, update read paths to use the new column exclusively. Add indexes only if query plans demand it—indexes during high load can hammer I/O. Monitor replication lag if your database cluster spans regions. Watch query performance in staging before flipping features on in production.