OPS-12 · SEC. 03 Operations & DevOps
Rollback Readiness Check
Before you deploy, confirm you can actually roll back, not just that the deploy itself is clean.
- FORMAT
- workflow
- DIFFICULTY
- intermediate
- TIME
- 10 min
- TOOLS
- claude-code · codex-cli
- MODELS
- any
- COPIES
- 0 so far
When to use this
You're about to deploy something riskier than a copy fix: a schema migration, a new required env var, a dependency bump. A clean build proves the deploy will start; it says nothing about whether you can undo it in five minutes if it goes wrong. Use this before those deploys, not after.
The pattern
Before I deploy this, check whether I can actually roll it back if it goes wrong. Do not just check that the deploy is clean, check that undoing it is possible and fast. First, work out what's shipping: identify the real production deployment from platform metadata, a verified deployment ID, or a release record. Do not assume the latest tag or default branch is deployed. If the deployed state is unknown, stop and report that instead of evaluating rollback. Diff the current branch against the verified deployed state and state the change in one line at the top of your report, e.g. "migration adding a NOT NULL column" or "new required env var STRIPE_WEBHOOK_SECRET". Then: 1. Identify the last known-good deployment (tag, commit hash, or platform deployment ID) and confirm it still exists and is redeployable. 2. If this change includes a database migration: state whether it's backward-compatible (the old code can still run against the new schema) or a breaking change. If breaking, name the specific rollback step (a down-migration, a manual SQL fix, or "this cannot be cleanly rolled back, only forward-fixed"). Don't assume "revert the commit" is enough. 3. If this change adds or renames a required config value (env var, feature flag, secret): confirm the OLD code path still works if that value is absent, or state plainly that rollback requires restoring the old config too, not just the old code. 4. State the actual rollback command or platform action (e.g. `vercel rollback` with the deployment ID from step 1, `kubectl rollout undo`, "revert PR + redeploy"). Give a measured rollback time only if it was previously exercised; otherwise mark timing UNTESTED. 5. Give a one-line verdict: ROLLBACK VERIFIED, ROLLBACK PARTIAL (name exactly what would not be undone), or ROLLBACK UNTESTED. This is readiness evidence, not deployment authorization.
Real example output
CHANGE: migration adding a NOT NULL `tenant_id` column to `invoices`, backfilled from `accounts.tenant_id`. 1. Last known-good: deployment dpl_8f2a1c (tagged v1.14.2), still live in Vercel's deployment history, redeployable in one click. 2. Migration is NOT backward-compatible: the old code doesn't set tenant_id on insert, so if we roll back the app code but not the DB, every new invoice insert fails on the NOT NULL constraint. Rollback step: run the down-migration (0042_add_tenant_id_down.sql) BEFORE redeploying old code, not after. 3. No new config values, N/A. 4. Rollback command: `vercel rollback dpl_8f2a1c`, but it must be preceded by the down-migration or the old code will 500 on every invoice write. In practice: down-migration takes ~30s on this table size, then rollback takes ~1 min. 5. VERDICT: ROLLBACK PARTIAL: a plain "vercel rollback" alone breaks invoice creation. Full rollback requires the down-migration first. The sequence is documented, but deployment still needs separate approval.
Why it works
"The deploy is clean" and "I can undo the deploy" are different claims, and conflating them is how teams discover mid-incident that rollback means restoring from a backup instead of clicking one button. Forcing a concrete rollback command and an honest partial/complete verdict turns an assumption into something you actually know before you need it.