The migration failed halfway. A single missing new column broke the build. Everyone stared at the logs, but the error was already clear: the schema had moved, the code had not.
Adding a new column is simple in theory. The complexity comes from timing, dependencies, and performance. In production systems, a new column can trigger full table rewrites, lock rows, or break downstream queries. Done poorly, it introduces downtime or silent data corruption. Done well, it is invisible and safe.
First, decide the column’s data type and nullability. Once locked in, changing them later is painful. If you need a default value, set it carefully—on massive tables, a default with a rewrite can stall migration for hours. Consider using a nullable column with backfill scripts, then adding constraints once the data is ready.
Second, plan deployments. Schema changes and code changes should be staged. Add the column first. Deploy code that writes to it next. Switch reads over last. Avoid simultaneous changes that increase the blast radius.