The database groaned under the weight of new features, and the sprint was already behind. You opened the migration file. The spec was thin: add a new column.
Adding a new column seems simple. In production, it’s not. Schema changes can lock tables, block writes, and cause downtime. A bad migration can bring the system down faster than bad code in main. The work is not about typing the SQL. It’s about doing it without breaking users.
To add a new column safely, start with a clear definition. Decide data type, nullability, default values. Watch for implicit locks. On large datasets, adding a new column with a default that’s not null can rewrite the whole table. The safer approach is often to add the column as nullable, backfill data in batches, then enforce constraints after the table is ready.
Use feature flags to decouple deployment from release. Add the new column, deploy, and write to it in parallel with the old one. Once reads and writes align, cut over. This preserves uptime and lets you roll back if performance tanks.