Adding a new column in a production database can be simple, but doing it without downtime or data loss demands precision. Every decision—type, default value, nullability—ripples through code, queries, and indexes. Done wrong, it locks tables, stalls requests, and floods logs with errors you can’t ignore.
Choose the column type based on exact requirements. Avoid generic types when a specific one enforces constraints at the database level. Set default values to ensure new rows behave predictably. If the column should be non-nullable, plan the backfill before altering the schema.
Schema migrations must be tested in staging with production-sized data. Monitor how long the ALTER TABLE command takes. In systems like PostgreSQL, adding a nullable column with no default is fast. But adding a column with a default can rewrite the entire table unless you structure it as two steps: add column, then update rows.
Version control for migrations prevents conflicting changes between teams. Keep each migration atomic and reversible. Run them through continuous integration where possible, and bundle schema plus application changes together so no deployment window exposes the app to missing columns.