Adding a new column sounds simple. It’s not. In production systems, the wrong approach can lock tables, slow deployments, and break dependent code. The right approach keeps services running while the schema evolves.
First, define the purpose of the new column. Is it nullable? Does it need a default value? Understand the data type, indexing needs, and relationship to existing fields. Adding a non-nullable column with a default to a large table can cause a full table rewrite in some databases. For PostgreSQL, consider adding it as nullable first, then backfilling data in batches, and only then enforcing constraints.
Plan the migration in steps. Use tools like Liquibase, Flyway, or direct SQL migrations under feature flags. Ship the schema change separately from the application changes that use it. This reduces rollback risk.
In distributed environments, check consumers of the table. A new column in a shared schema can break deserialization in older services. Always version APIs and data contracts before relying on new fields.