Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLX · Forward Fix versus RollbackDecisionFramework

The decision framework — what makes rollback safe and what makes forward-fix the only option

Advanced⏱ ~20 mingit

What you'll learn

  • Apply the four properties - idempotency, reversibility, data effects, dependency reach - to classify a change
  • Map a change onto the rollback-versus-forward-fix decision matrix
  • Recognise why the reflex answer "always roll back" is wrong as a default
  • Treat the rollback-versus-forward-fix choice as a deliberate decision documented before the change ships

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

The reflex answer to a production incident is “roll back”. The reflex answer to a bad data migration is “forward-fix”. Both reflexes are wrong as defaults. The discipline of Part LX is to make the choice before the change ships, on the basis of four properties of the change itself.

The four properties

Every change has four properties that together determine whether rollback or forward-fix is safe:

  • Idempotency. Can the change be applied twice without a different effect? An idempotent change can be re-applied; a non-idempotent change (allocates resources, increments counters) can be applied once and only once.
  • Reversibility. Can the change be reverted by removing the new state? An additive change is trivially reversible; a destructive change may require a backup restore.
  • Data effects. Does the change write data the rollback cannot unread? A schema migration that adds a column is data-neutral; one that drops a column writes data the rollback cannot restore.
  • Dependency reach. How many systems does the change touch? A workload-only change has a narrow reach; a change that crosses schema, config, and cloud has a wide reach.
flowchart LR
    A["Change classified"] --> B{"Data written?"}
    B -- "yes" --> C["Forward-fix by default"]
    B -- "no" --> D{"State destroyed?"}
    D -- "yes" --> E{"Backup available?"}
    E -- "no" --> C
    E -- "yes" --> F["Restore or forward-fix"]
    D -- "no" --> G{"Idempotent?"}
    G -- "yes" --> H["Rollback is safe"]
    G -- "no" --> I["Forward-fix with care"]

The decision matrix

No data effectsData effects
IdempotentRollbackForward-fix
Non-idempotentForward-fix with careForward-fix

The four quadrants: idempotent with no data effects rolls back (config, image, deployment bug); idempotent with data effects forward-fixes (additive schema migration); non-idempotent with no data effects forward-fixes with care (resource allocation); non-idempotent with data effects forward-fixes (destructive migration).

Why classification is not a reflex

The reflex to roll back is correct in the common case (idempotent, no data effects) and wrong when the change has data effects. The discipline is to classify the change before it ships:

  1. At design time. The author declares the classification in the pull-request template.
  2. At review time. The reviewer confirms the classification against the four properties.
  3. At deploy time. The deploy annotation carries the classification; the on-call engineer sees it without re-deriving it.
  4. At incident time. The on-call engineer follows the documented path for that classification.

Production discipline

  1. Classify every change at design time. The pull-request template asks for the rollback-versus-forward-fix classification.
  2. Record the classification in the deploy annotation. The Kubernetes change-cause annotation, the GitOps commit message, the CI deploy summary all carry it.
  3. Document the rollback path for every change. Even forward-fix changes need a documented rollback path.
  4. Treat the classification as a deliverable. A “forward-fix” classification without a documented forward-fix is a guess.

Cross-course references

  • This course, Part LIX-03 and LIX-04 cover the mechanisms the classification decides between.
  • This course, Part LIX-06 covers the data effects quadrant in depth.
  • PostgreSQL for Production Sysadmins - Part XXIV covers expand-and-contract.

Quiz

Knowledge check · 4 questions

  1. Q1. A team bumps a Deployment's container image from `api:v1.2.3` to `api:v1.2.4` with no other changes. After 10 minutes the application reports a startup crash. Which path is the correct default response?

  2. Q2. The reflex answer to a production incident should be to roll back the change, because rollback is the safer default for any deployment.

  3. Q3. Name the four properties of a change that determine whether rollback or forward-fix is the safe response, and identify the one most often overlooked at design time.

  4. Q4. Diagnose why a rollback made a production incident worse, and identify the property the on-call engineer should have checked before running the rollback.

    A team deploys a schema migration that adds a `users.email_verified` column with a default of FALSE, then runs a backfill that sets the value to TRUE for users created before 2024. The application reports long-time users being asked to re-verify. The on-call engineer runs the migration tool's down script; the rollback drops the column. The next morning, the audit team reports the email_verified status for 2.3 million users is permanently lost.

Passing score: 75%. Answers are checked in this browser.