The query was simple: add a new column. The cost in production could be anything but.
Schemas are promises. Every table, every column, every constraint is a contract your system has signed. Adding a new column is not just a schema change—it's a migration of reality in a live environment. Done right, it’s invisible. Done wrong, it breaks deployments, locks tables, or introduces downtime you can’t afford.
Before you run ALTER TABLE, you need certainty about type, nullability, defaults, and indexing. A boolean flag? Varchar? JSONB? Choose the wrong type and you’re setting traps for future work. Even a default value can cause a write lock if applied to millions of rows.
Use backward-compatible migrations whenever possible. Add the new column without constraints first. Backfill data in small batches. Apply not-null or uniqueness constraints only after the data is complete and consistent. On large datasets, use tools like pt-online-schema-change or built-in online DDL capabilities to avoid blocking reads and writes.