A database schema looks permanent until the moment it must change. Adding a new column in production is never just “one more field.” It can push indexes off balance. It can lock tables for seconds or minutes. It can trigger migration scripts that fail halfway through and leave you with ghost data.
The steps are clear, but the order matters. First, define the new column in development. Choose the data type with care. Small integer or bigint? Text or varchar with a strict limit? Every choice affects storage, query speed, and future scalability. Test locally with realistic data volumes.
Next, run migrations in staging with the same workload you expect in production. Watch query plans. Monitor locks. Measure I/O impact. If the table is large, consider ADD COLUMN with a default value set to NULL first. Populate data in batches using update scripts to avoid downtime.
For distributed systems, coordinate schema changes with code deployments. Deploy new code that ignores the new column before it exists, then deploy migrations, then deploy code that reads it. This avoids race conditions and mismatched reads across nodes.