Adding a new column sounds simple. It rarely is. The risks stack fast: locks on large tables, replication lag, failed deployments. The wrong approach can slow queries, block writes, or take your database offline. The right approach is fast, safe, and reversible.
First, define the new column in a way that doesn’t block your system. Use NULL or a safe default to avoid rewriting large amounts of data. Avoid setting NOT NULL with a default value during the initial change on massive tables—it will lock them.
Second, deploy the migration in small, controlled steps. Create the column without constraints. Backfill data in batches to avoid load spikes. Only after the column is populated should you add indexes or constraints.
Third, maintain backward compatibility. Shipping a new column before the application code knows how to use it can cause dead features or broken queries. Use feature flags or conditional logic so old and new code paths can run in parallel.