The fix was simple: create a new column.
Adding a new column sounds trivial, but in production, it can be risky. Schema changes affect uptime, query performance, and application logic. Poor planning can lead to locks, timeouts, or broken deploy pipelines. The right approach depends on the database engine, the table size, and the traffic pattern.
In PostgreSQL, adding a nullable column without a default is fast because it updates the system catalog without rewriting the table. Adding a column with a default value can trigger a full table rewrite, blocking access for large datasets. MySQL also differs: some operations lock reads and writes, others don't, depending on the storage engine and column type.
Before adding a new column, check for dependencies in code, triggers, views, and stored procedures. Use feature flags to roll out the changes in stages. First, add the column with no default in a migration step that runs instantly. Second, backfill data in small batches to avoid load spikes. Finally, add constraints or defaults in a separate migration once the data is in place.