Adding a new column sounds simple. In production, it can be anything but. Done wrong, it can lock tables, degrade performance, or trigger cascading failures. Done right, it can evolve your database without downtime or data loss.
The first step is to define the new column with precision. Decide on type, nullability, and default values. Every choice here affects storage, indexing, and queries. Avoid unnecessary defaults unless you need them for migrations that must be instantaneous.
When dealing with large datasets, a direct ALTER TABLE ADD COLUMN can freeze operations. Use online DDL operations if your database supports them. PostgreSQL’s ADD COLUMN with a default value rewrites the table; MySQL’s ALGORITHM=INPLACE can avoid that. Test each option against production-like workloads before running it live.
Backfill strategy matters. Add the new column as nullable, deploy the change, then run background jobs to populate values in small batches. Once backfilled, add constraints or make it non-nullable as a separate migration. This reduces lock times and makes rollbacks easier.