Skip to content

Roll Forward Recovery

Recovery is a forward Git change that moves the declared system state to a safer state. The forward action may be a targeted fix, feature flag change, revert commit, values-file re-pin, or reviewed data repair.

How recovery choices relate

When an incident hits production, pick the fastest safe recovery path. Each option routes through different verification steps because not all paths carry the same runtime risk.

flowchart TD
Incident["Production problem"] --> Choice["Choose safest recovery path"]
Choice --> RollForward["Roll forward with fix"]
Choice --> Revert["Revert with new commit"]
Choice --> Rollback["Rollback to prior version"]
RollForward --> Verify["Verify service and data"]
Revert --> Verify
Rollback --> Risk["Check schema, data, and compatibility risk"]
Risk --> Verify

Rollback adds an extra verification gate: confirm the older version is still compatible with the current runtime before it runs. Roll-forward and revert skip that gate because they deploy code shaped by the runtime changes already in Git.

The terms

TermWhat it meansBest-case windowWorst-case risk
Roll forwardFix the problem in a new commit and deploy it5-15 minutes for a simple one-line fixFix is complex, the fix has a bug, or incident pressure masks the real problem
RevertCreate a new commit that undoes a recent change3-5 minutes with git and deploy automationReverts needed code alongside the bad code and breaks dependent systems
RollbackRedeploy an older version from a prior state2-3 minutes with an existing artifactOld code is incompatible with current schema, messages, cache keys, or vendor APIs

Preference

We prefer roll-forward recovery, including revert commits, because it moves Git forward and avoids silent state collisions.

Rollback

Rollback seems fastest but introduces a hidden problem: you’re redeploying code that may be incompatible with the current runtime state. If any commit since the rollback target touched the database schema, cache key structure, message format, or external API contract, the old code may fail to read the new state or silently corrupt data. A two-minute rollback can mask a two-hour data-recovery incident.

Revert commits

Revert commits are safer than rollback because they respect the current data state, but a revert only works when the problem is isolated to a change that nothing else now depends on. If the revert removes a schema migration, API shape, or feature flag path that later commits require, it becomes its own incident.

Roll-forward fixes

Roll-forward fixes directly address the real problem: identify what is wrong, fix it, and deploy the fix. This is fastest when the fix is clear and small. The risk is incident pressure, so keep the change narrow and verify the service and data immediately after deploy.

Rules

  • If it changes runtime behavior, it belongs in Git.
  • Do not repair the cluster by hand and leave Git unchanged.
  • Emergency work can move faster, but it still uses PRs, review, checks, and audit history.
  • main must stay deployable; unfinished user-facing behavior belongs behind a flag.
  • Stabilization is not complete until the follow-up owner and due date are recorded.

Forward actions

ActionUse whenWhat changes
Fix forwardCause is clear and the fix is smallNew corrective commit
Feature flag offRisky behavior is already behind a flagFlag default or targeting
Revert commitBad change is isolated and safe to undoNew revert commit
Re-pin tagSeveral commits need to be bypassedEnvironment values file
Data repairData shape is part of the incidentReviewed data or schema fix

Even git revert is a new commit. That is the point: recovery stays reviewed, visible, and auditable.

Why not classic rollback

Redeploying the previous artifact can be risky when the current database schema, queued messages, feature flags, cache shape, or external records have already changed. Use rollback only when roll-forward or revert would take unacceptable time and you have verified no schema, format, cache, queue, or contract changes since the prior version.

Emergency branch policy

Use an allowed branch prefix, usually fix/ or revert/, plus an incident reference in the PR.

FieldExample
Branchfix/prod-login-timeout
PR titlefix(auth): restore login timeout handling
Incident refINC-2026-0610
Follow-upAdd regression coverage and incident action item

Do not use hotfix/ or emergency/ as branch prefixes.

Avoid

  • editing Kubernetes resources by hand
  • patching a pod or container directly
  • changing ArgoCD UI state without committing the same Git state
  • bypassing checks because the change is small
  • bundling cleanup into emergency recovery
  • leaving stale flags after stabilization

Incident follow-up

After service is healthy, identify why the issue reached users or blocked an environment. Common causes include missing tests, weak UAT, unclear requirements, unreliable infrastructure, incomplete monitoring, and migration risk. The incident is done only when the root prevention work has an owner, date, and tracked fix.

Automation

Automation may alert, link the incident to a release commit, and open draft revert, flag-default, or re-pin PRs. Humans still choose the recovery path when data, migrations, or external side effects are involved.

Evidence

Retain the recovery PR, incident timeline, ArgoCD sync record, release or values-file diff, and post-incident action items.

See also