Lesson 13 · Senior platform judgment
Fix-forward migrations, schema safety, and rollback judgment
How to reason about forward-only schema change systems, why “no rollback” can be defensible, and what extra discipline that decision demands.
Your win: explain why a forward-only migration model can be a rational platform decision, what risks it shifts onto review and rollout discipline, and how to defend it honestly in an interview.
Why this page matters more than it first looks
At first glance, this can feel like a small repo-specific quirk: “this codebase has no down migrations.” But the stronger lesson is not about memorizing that fact. The stronger lesson is about understanding what kind of operational promise the platform is making.
Once you see it that way, the topic gets much more interesting. A forward-only system is not removing risk. It is deciding where the risk should live: less in rollback machinery, more in review quality, additive schema design, rollout caution, and fast corrective follow-up.
What “no rollback” is really saying
The most senior explanation does not pretend rollback is always clean. In real systems, schema rollback gets messy fast once live writes have landed, multiple services depend on the new shape, or cleanup depends on data that has already changed. Some teams decide that a nominal rollback path creates more confidence than real safety.
So they standardize on a different recovery motion: when something is wrong, ship the next corrective migration. That choice is not automatically better. It is a trade-off. You gain one consistent recovery path, but you lose the psychological comfort of a reverse button.
m.Up(), there are no .down.sql files, and schema correction happens by writing a new forward migration rather than rewinding an old one.What changes for review and rollout
This is where the topic becomes practical. If rollback is not your normal move, then the safety burden shifts earlier. You care more about additive changes, backwards-compatible intermediate states, data backfill sequencing, and rollout plans that are boring on purpose.
That is the real senior move here: not just naming the trade-off, but naming the behaviors that make the trade-off survivable.
Compare the canonical tool to the repo choice
Read golang-migrate’s normal model beside the repo wrapper so the repo’s opinionated choice stays visible.
Check yourself (from memory)
Q1. What is the strongest senior defense of a fix-forward migration system?
Sources. golang-migrate docs; repo toolkit map.