Adding a new column to a database sounds simple. It’s not. Schema changes can block writes, lock tables, and cause downtime if handled wrong. The right approach keeps your service online, data consistent, and deploys without surprises.
First, decide if the new column should allow nulls or have a default value. Adding a nullable column is fast in most modern databases. Non-null columns with defaults can cause the engine to rewrite the table, which is expensive at scale. In PostgreSQL 11 and later, adding a column with a constant default is optimized—older versions are not. MySQL behaves differently and may need more care.
Second, design for backfill. If the new column must contain computed data for existing rows, write an idempotent backfill job. Run it in batches to avoid locking. Monitor the operation. Do not block the schema migration with the backfill—deploy them as separate steps.
Third, deploy in phases. Phase one: alter the table to add the new column as nullable. Phase two: deploy code that writes to both the old fields and the new column. Phase three: backfill historical records. Phase four: switch reads to use the new column. Phase five: remove old fields if necessary. Each step should be reversible.