Doing it by hand in a database console is where data goes missing. Nothing records what was run, staging drifts away from production, and the change that worked in testing behaves differently against real rows.
The part people underestimate is that a migration runs while the application is still using the data. A change that locks a large table for a minute is a minute of downtime, which is why serious migrations are often split into several deliberately small steps.
Updated September 2026