Adding a new column sounds simple. In production, it is not. Schema migrations touch live data, running queries millions depend on. A single misstep can lock writes, stall reads, or corrupt what you cannot replace. The goal: evolve without breaking.
Start by defining the new column in your migration script. Choose the right data type. Size it for the future but keep storage tight. If the column must be indexed, weigh the cost. Index creation can block transactions. For high-traffic systems, create non-blocking indexes or build them concurrently.
Run migrations in stages. First, add the column as nullable. This avoids costly default-value writes when the table is large. Next, backfill data with a batch job, throttled to prevent load spikes. Monitor query performance. Watch latency and cache hit rates. Keep replication lag in check.