Adding a new column sounds simple. In practice, it can break production if you miss a step. The best approach protects data, preserves uptime, and avoids locking large tables. A new column must fit the schema, carry the right data type, and play well with indexes and queries.
Start with the plan. Define the column name, type, and constraints. Check naming conventions, reserved words, and backward compatibility with existing code. If the column holds JSON or large text, understand the storage and performance tradeoffs.
In relational databases like PostgreSQL or MySQL, adding a nullable column with a default value is straightforward. But on large datasets, adding a column with a default can rewrite the entire table. To avoid downtime, add the column without a default, backfill data in small batches, then set the default in a separate statement.
If you're using migrations, keep them atomic and reversible. A migration that adds a new column should also contain a rollback path. For zero-downtime deploys, pair schema changes with code changes using feature flags or conditional logic. Code should be able to operate without the new column until it's live everywhere.