Adding a new column seems trivial, but that’s only true for isolated dev environments. In production, it’s about precision: migrations, constraints, defaults, and indexing strategy. If you do it wrong, you lock tables, block writes, and stall your application.
The safest path is to design the change in small, reversible steps. Start with an additive migration: create the new column as nullable, without a default, to avoid table rewrites on large datasets. For PostgreSQL, this means ALTER TABLE ... ADD COLUMN with no heavy computation in the statement.
Backfill data in batches. Use short transactions. Keep locks minimal. Run it in the background so user operations remain uninterrupted. Only after the column is populated should you set defaults or enforce constraints. If you need an index, build it concurrently to prevent blocking reads and writes.