Migration rollback

Read this page in the documentation

Migration rollback A migration reached production and should not have. First: can it be rolled back at all? That depends on what it did, not on the tooling. The migration | Reversible? | --- | --- | Added a table, column or index | Yes — dropping it loses nothing that existed before | Widened a column, dropped a constraint | Yes | Dropped a column or table | No — the data is gone unless you have a backup | Narrowed a type (TEXT → VARCHAR(50)) | No — truncated values are not recoverable | Backfilled or transformed data | Only if you recorded the previous values | Run down on the first two groups. For the rest, restoring from a backup is the real remedy and down is theatre. Rolling back Check migrate:status first. If several migrations shipped together, undoing one may leave the schema in a state no migration describes. Rolling forward is usually better A down that drops a column deletes production data to undo a deploy. A forward fix does not: Prefer forward unless the migration is provably reversible and provably empty of new data. Why the expand / migrate / contract shape exists It makes every step individually reversible: 1. Expand — add the new column, nullable. Reversible: nothing reads it yet. 2. Migrate — write both, backfill, then read the new one. Reversible: the old column is still authoritative. 3. Contract — make it NOT NULL, drop the old column. Not reversible — which is why it is last, and separate. Stopping between two and three leaves a working system. That is the point. The Gantt example draws the shape. If the schema no longer matches the models Tells you what actually differs before you write a corrective migration. See Schema diffing. Before the next one Take a snapshot before any migration that drops or narrows. Run it against a restored copy of production first — staging with 40 rows does not surface a lock held for eight minutes over 40 million. Keep migrations small: one concern each, so undoing one does not undo four. Related reading Migrations Schema diffing Query interface