Adding a new column to a production database should be simple. One command. One migration. But in reality, it can trigger lockups, downtime, and chaos if done without care. The difference between shipping fast and breaking production comes down to understanding how to create, deploy, and backfill that new column with zero disruption.
Start in development. Define the new column in your migration script with an explicit type, nullability, and default value if required. Avoid implicit defaults that can trigger a full table rewrite. In SQL databases like PostgreSQL, ALTER TABLE ADD COLUMN is fast when no default is set; a separate backfill step can update rows in smaller batches. This protects query performance during the migration.
For large datasets, use transactional DDL only when safe. Otherwise, break the process into discrete steps: add the new column without constraints, backfill incrementally, then add the NOT NULL or foreign key constraints in a separate migration. This reduces the risk of long-running locks and allows safe rollbacks.