Adding a new column sounds simple. In production, it is not. Schema changes risk downtime, failed migrations, or inconsistent data. A poorly executed migration can lock writes, block reads, or burn your error budget. Speed matters, but safety matters more.
The first step is planning. Define the column name, data type, default value, and constraints. Check for backward compatibility. Ensure code can handle the new column before it exists. Deploy application changes to ignore missing fields and accept future values.
Next, write the migration. If the database is large, break it into stages. Create the new column without a default to avoid locking the table. Backfill in batches, with controlled transaction sizes. Monitor performance and replication lag. Once backfilled, set defaults and constraints in a second migration. Release the application code that uses it.