The query returned before you expected, but something was off. The table was missing the new column you just added. You check the migration logs. You check the schema. You confirm the code was deployed. Still, production isn’t matching your mental model.
Adding a new column should be fast, repeatable, and safe. In modern systems, schema changes can be the most fragile part of shipping. Blocking queries, data type mismatches, stale caches, and deploy order all create risk. When a new column is introduced, the database engine must allocate space, update indexes, and sometimes rewrite large chunks of data. Doing this without downtime means planning.
The most reliable pattern is to break the change into stages. First, add the new column as nullable and without default values. This keeps the DDL operation minimal and reduces lock contention. Then backfill data in small batches, using application code or background workers to avoid blocking reads and writes. Once the column is populated, enforce constraints or add indexes in a second migration.