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.

In plain English Plain English: if you choose not to rewind the database, you must become better at moving forward safely.

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.

The fix-forward rule A forward-only migration system can be safe, but only if review, additive schema design, and follow-up corrective migrations are treated as first-class operational discipline.

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.

Backend use case In this repo, the migration wrapper only calls m.Up(), there are no .down.sql files, and schema correction happens by writing a new forward migration rather than rewinding an old one.
Common mistake Treating “no rollback” as either obviously reckless or obviously safe, instead of explaining the discipline it requires.

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.

Read this next

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.

golang-migrate — MIGRATIONS.md
Repo toolkit map

Check yourself (from memory)

Q1. What is the strongest senior defense of a fix-forward migration system?

The mature answer is about operational trade-off, not absolutism.
Why can a forward-only migration model be defensible?
recall, then click to reveal
Because rollback is often not truly simple once live data and dependent services have moved. A forward-only model standardizes recovery around new corrective migrations, but demands stronger review and additive-change discipline.
Want a “would this migration plan be safe in a fix-forward system?” review drill? Ask me.

Sources. golang-migrate docs; repo toolkit map.