Line one of a rollback plan names the exact release you would go back to, by deployment id or commit. What is a rollback plan? One page of 7 lines: that release, the trigger, who decides, the steps on your host, the database half, the checks afterward and who tells customers, proven by a drill on a test release.
What is a rollback plan: the seven lines
A rollback plan is one page with 7 lines: the known-good release and how to find it, the signals that mean roll back now, who decides and who acts, the steps on your host, what happens to the database, the checks afterward, and who tells customers. It counts only once the steps have been tried.
The page is one step of the release path that DevOps for startups walks through, and a deploy-day checklist carries it as one of its items. If you have no plan for rolling back a deploy today, start here: filling in these lines comes before any tooling.
Here is the page as a rollback plan template you can copy into your repository’s docs folder or your team wiki and fill in:
ROLLBACK PLAN: <app name> last rehearsed: <date>, took <minutes>
1. Known-good release: <deployment id, git tag or commit SHA>.
Release list kept at: <link>. Host still keeps it: <yes/no>, checked <date>.
2. Roll back now if: <checkout fails> | <sign-in fails> | <error rate above the alert line>.
Anything else: fix forward.
3. Decides: <name>. Acts: <name>. Second person: <name, or the written fallback>.
4. Steps on <host>: <numbered clicks or commands>.
Last steps: turn normal deploys back on (<how>), then merge the revert pull request.
5. Database: this release changes <nothing / adds column X / renames column Y>.
Old code runs on the new schema: <yes/no>. If no: <two-step release or restore path>.
6. Checks afterward: <version marker> returns <previous value>;
smoke journeys: sign in, <core action>, payment up to the provider hand-off;
data spot check: record <id> still there.
7. Tells customers: <name>, on <status page, email or in-app banner>.
Line 1 is a pointer, not a memory: a deployment id from the host’s list, a git tag you push on every release, or a commit SHA, written where the person on line 3 can find it in the middle of the night. The trigger line holds two or three signals at most, so the decision takes seconds, and everything not on it gets a fix forward instead. People go on line 3 by name, and a solo founder writes the fallback down instead (who has the host login if you are on a plane). Only line 4 differs by host, and its last two steps are the ones that stop the rollback from undoing itself. You fill in line 5 before each release that touches the database, not once. The wording of the customer message on line 7 belongs in your incident response plan; this line only says who sends it and where.
My working rule: a page like this becomes a rollback plan only once lines 4 and 5 have been tried on a real release. Until then it is a guess with numbered lines.
What goes wrong without it
Six ways a deploy broke production and left no way to roll back, or rolled back and stayed broken, are in the rows below, each with the line of the plan that covers it.
| What happened | Why there was no way back | The plan line that covers it |
|---|---|---|
| The deploy broke production and nobody could roll back | The host keeps previous deployments but nobody knew where; the good one had aged out of what the host keeps; or the app was deployed from a laptop with no record of the last good build | Lines 1 and 4 |
| The code went back and the app stayed broken | The release had dropped or renamed a column the old code still reads | Line 5 |
| The rollback worked and the bug stayed | The cause was outside the build: a changed database, an external API or a CMS. Vercel’s rollback dialog shows “A reminder about the changing behavior of external APIs, databases, and CMSes used in the current or previous deployments” | Lines 5 and 6 |
| A revert commit sat in a slow pipeline while checkout was down | Going back meant a full build and deploy, with no faster route written down | Line 4 |
| An AI builder’s revert restored the code in the editor, not the published app | The builder’s history and the live deployment are two separate things: Lovable’s revert redeploys only the edge functions, and the published app changes on the next publish | Line 4 |
| A fix was merged after the rollback and never went live | The host had paused automatic production deploys (Vercel after an Instant Rollback, Render after a dashboard rollback) and nobody turned them back on | Line 4, last step |
Row 4 is as much about pipeline speed as about rollback: knowing how to speed up CI build times shortens the slowest of the ways back. Row 5 is a builder problem, and the Lovable cases are set out in when Lovable’s revert does not work.
Row 1 has a quieter version. Take a founder whose app runs on a managed host that lists past deployments with a rollback action, where nobody has written down which release was the last good one. A bug that shipped several releases ago turns up; the last release without it is older than the host keeps, so the host does not offer a rollback to it, and the way back becomes reverting the commits and building the old code again through the pipeline. The lesson I take from it: line 1 names a release the host still keeps, and line 4 carries the rebuild path for anything older.
At least 17 of the 21 third-party apps had no deploy gate, and so did all 5 founder apps: every push ships straight to production with nothing checking it first. All of them, the 21 and the 5, are apps I audited in June and July 2026, a selected set rather than a random sample, so the count says nothing about the rate across AI-built apps in general. My reading of it: with nothing checking a release before it ships, the way back is the safety that is left.
How to roll back a bad deploy: the steps line, by host
A rollback from a bad deploy can go 3 ways, fastest first: switch the feature off if it has a switch, point production back at the previous build with the host’s rollback, or revert the commit and redeploy. A host rollback leaves the bad commit on main, so the revert pull request still has to follow.
The ordering is mine. A feature switch takes effect without a deploy at all, which is why kill switches and open source feature flags sit above everything else when the broken code is behind one. The host’s rollback is next: it reuses a build that already exists. The revert is slowest, because it waits for a full build, and it is the only one of the three that also fixes the repository.
That last point is why line 4 never ends at the rollback button. After a host rollback, main still holds the bad commit. Once normal deploys resume, the next deploy from main ships the bug again unless the revert has landed first, so the step list ends with the revert pull request, and that pull request goes through the same GitHub branch protection as any other change. Each dependency update a bot merges is a release too and needs the same way back, so ask before the first incident: what is Renovate bot allowed to merge without a person?
The click paths for Vercel and Netlify, and the choice between rolling back and fixing forward, are in how to roll back a deployment on Vercel or Netlify. The table below gives the plan line for each common place an app is deployed, from each host’s own docs.
| Where you deploy | How you go back | What stays as it is | How normal deploys resume | Source (checked 2026-10-04) |
|---|---|---|---|---|
| Vercel | Instant Rollback in the dashboard, or vercel rollback [deployment-id or url]; only deployments previously aliased to a production domain are eligible | External APIs, databases and CMSes; environment variables changed in project settings are not applied to the older build | Promote a deployment (Undo Rollback, or vercel promote), which turns auto-assignment of production domains back on | Vercel docs |
| Netlify | Steps and the deploy lock are in the Vercel and Netlify walkthrough above | As in that walkthrough | As in that walkthrough | The walkthrough above |
| Railway | The deployment menu’s Rollback “Redeploys the selected deployment”, using its source code; deployments older than the plan’s retention policy show no rollback option | Not stated in Railway’s docs | Not stated in Railway’s docs | Railway docs |
| Render | Rollback on the Deploys page or through the API starts a new deploy from the target deploy’s build artifact, while that artifact is still retained | Disks, compute plan, custom domains, and static site redirects, rewrites and headers keep the current configuration | A dashboard rollback disables autodeploys until you re-enable them in Settings; an API rollback leaves them on, so the next push deploys | Render docs |
| Your own pipeline (GitHub Actions) | Run the deploy job against an older ref (next section) | Whatever the deploy job does not touch, such as the database | Whatever your push trigger does; if it deploys on every push to main, the next merge ships | GitHub docs |
| An AI builder (Lovable, Replit, Base44) | The builder’s own revert or history, then publish | The database the app writes to | Publish again from the builder | The undo article in the previous section |
| Kubernetes | kubectl rollout undo deployment/<name>, which undoes a previous rollout | Not stated in that reference | Not stated in that reference | Kubernetes docs |
The host pages behind the table are the vercel rollback CLI reference, Railway’s deployment reference, Render’s rollback documentation and kubectl rollout undo. How automatic deploys behave after a Railway rollback is not stated in Railway’s docs, so the drill below is how you find out: after rolling back its harmless test release, push another harmless commit and watch whether it deploys.
Vercel Instant Rollback: what the plan records for it
For a Vercel project, line 1 names a deployment that was aliased to a production domain, since only those are eligible, and on Hobby the only target is the immediately previous deployment. If you need to reach further back, that is a plan difference, and the Vercel price of each plan is where the cost sits. Line 4 ends with promoting a deployment, because after a rollback Vercel turns off auto-assignment of production domains, and line 5 is written anyway, because Vercel treats the rolled-back deployment as a restored version of a previous deployment and your database is not part of any deployment. Both behaviors are in Vercel’s Instant Rollback documentation.
One header needs its own line, and this part is my reading. Headers set in the repository’s config come back with the older deployment, but HSTS lives in the browser: under RFC 6797, HTTP Strict Transport Security, the max-age value is the number of seconds after receiving the header during which the browser regards the host as a known HSTS host. So if the bad release added or lengthened that header and the older one sends none, browsers that already saw it keep enforcing it after the rollback. That is why HSTS goes up in stages, a ladder that is part of man-in-the-middle prevention. The dashboard steps and what the button does and does not restore are in the walkthrough already linked.
Rollback deployment with GitHub Actions
A rollback in GitHub Actions is the normal deploy job run against an older ref: a manual trigger with a ref input, building from that commit’s own lockfile. Keep recent build artifacts or image tags, so going back never depends on a fresh build passing.
When your own pipeline deploys (to a VPS, a container host or a static bucket), you do not need a second rollback system. Add a workflow_dispatch trigger with an input for the ref, and check that ref out with actions/checkout, whose ref input takes “The branch, tag or SHA to checkout”.
name: deploy
on:
push:
branches: [main]
workflow_dispatch:
inputs:
ref:
description: 'Commit SHA or tag to deploy (rollback)'
required: false
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
ref: ${{ inputs.ref || github.sha }}
- run: npm ci && npm run build
- run: ./scripts/deploy.sh # your existing deploy step
On a push the input is empty and the job deploys the pushed commit; run by hand with a SHA, it builds that commit with that commit’s own lockfile, not today’s. GitHub’s workflow_dispatch event only triggers a run if the workflow file exists on the default branch, so merge this before you need it. If a rebuild is slow or fragile, my working rule is to keep the last few build artifacts or image tags and point the rollback job at those instead.
Never force-push main to undo a release. git revert records new commits that reverse the effect of some earlier commits, often only a faulty one, and keeps the history everyone else already has. How the pipeline itself should be built is a question for CI/CD best practices.
The database half: when rolling back the code is not enough
A host rollback moves code and never the database, so the plan sorts every release into 5 cases. No schema change, or an additive one, is safe to roll back. A renamed or dropped column is not, and ships in two steps. A destructive data change can only be restored from a backup.
What the plan adds is deciding, before each release, which of these cases it is. The verdicts in the table are my rules, and the third column is the sentence that goes on line 5.
| What the release changes in the database | Is a code rollback alone safe? | What the plan line says |
|---|---|---|
| Nothing in the schema | Yes | ”No database change in this release.” |
| Adds a nullable column or a new table | Yes: the old code ignores it | ”Additive only; the old code runs on the new schema.” |
| Renames or drops a column, or tightens a constraint | No: the old code reads a column that is gone, or writes rows the new rule rejects | ”Ships in two steps; this release only adds, the removal waits for the next one.” |
| Backfills or rewrites data, or runs a destructive migration | No rollback reverses it | ”Backup taken at <time> before the release; restore path <steps>; only <name> may choose it.” |
| Changes RLS policies or database functions | Only with a reverse migration written and tested beforehand | ”Reverse migration <file>, tested on staging on <date>.” |
The two-step release is also the answer to how to run database migrations on deploy without stranding the previous build. Reversing a Supabase migration, what supabase migration down really does, and when a restore is the only path are covered in what a Supabase migration rollback actually reverses.
A restore is the last resort, and it loses everything written since the backup. Supabase currently documents in-place PITR as making the project inaccessible during the restore, so line 5 also says who may choose it. It also needs a backup to exist: Supabase backs up Pro, Team and Enterprise projects daily, and PITR is an add-on on those plans. For free projects, Supabase recommends regular exports with the Supabase CLI db dump command and off-site backups, so a free project’s plan names the export taken before the release. Whether that copy restores at all is a different exercise, a restore drill for your backups, not the release drill below. Recovering the whole system after losing a host or a region is the job of the disaster recovery checklist for SaaS. SQL’s ROLLBACK statement, which undoes one open transaction, is a different thing from all of this.
How to verify it: test the rollback of a release
A rollback is verified by a rehearsal of 8 steps: ship a harmless test release with a version marker, create a test record, call the failure, follow the written steps, confirm the old version is serving and the record survived, then write down the elapsed time and turn normal deploys back on.
Run it on a quiet day: against production when the test release really is harmless, and against a production-like staging copy when it cannot be, for example when every deploy also runs migrations. This is the rollback rehearsal checklist, and step 4 is where you test rollback on a simulated failure rather than a real one:
- 01 Add a version marker the outside world can read: a /version route or a build id in the footer, set from a value committed in the code so a rebuild of an old commit still shows the old value.
- 02 Ship a test release whose only change is that marker and a visible harmless string, reviewed on a preview first.
- 03 Once it is live, create one record through the app in a test account your team owns, never a customer's, so there is data newer than the deploy, and note its id.
- 04 Simulate the failure: tell the person named as the decider that the test release is broken, and start the clock.
- 05 Follow the steps line exactly as written, touching nothing that is not on the page.
- 06 Verify behavior: the version marker returns the previous release's value, and the smoke journeys pass: sign in, the core action, and the payment journey as far as the hand-off to the payment provider.
- 07 Verify retained data: the test record created after the release is still there and readable.
- 08 Stop the clock, write down the time and every step that was wrong or missing, fix the page, then turn normal deploys back on the way the steps line says and confirm the next release goes live.
Step 2 needs a preview of the test release, so settle one question before drill day: what are preview deployments on your host, and who can open them? On Vercel, the result of step 5 shows on the project’s production deployment tile, which highlights the canceled and rolled-back commits. Never run a test-mode payment against production in step 6; that belongs on a staging copy with test keys.
Then run a second rehearsal for the database half, on a staging copy or a preview with its own database: ship a release with an additive migration, put the code back to the previous release, and run the smoke journeys again to prove the old code still works against the migrated schema. On Vercel that means redeploying the previous commit, since most preview deployments are not eligible for Instant Rollback.
The pass condition: the rollback is completed from the page alone, by a second person where the team has one. A solo founder writes down every step they had to recall from memory, and each one goes onto the page. Keep the evidence: the two deployment ids, the version responses before and after, the record id, the elapsed time and the date. Repeat the drill after any change of host, pipeline or migration tool. The six-item rehearsal list in the Vercel and Netlify walkthrough covers access, eligibility and escalation; this drill adds the harmless test release on the real host and the retained-data check.
In the Production Hardening Sprint, deliverable 7.6 is verified this way: Roll back a test release and verify application behavior and retained data.
Where the sprint does this
Deliverable 7.6 of the Production Hardening Sprint, Tested rollback, is to document and rehearse release rollback, including how database changes are handled safely. The production readiness report, deliverable 13.1, records the result for every scope item, the work completed, and its verification evidence. Post-handover support is 14 calendar days of fixes for defects in the delivered sprint work. Your app’s current framework and hosting setup are the starting point; components are refactored or replaced where the production work requires it. The rest of the release work sits in area 7 of the published scope.
Common questions about rolling back a release
What does rollback mean?
Rollback means going back to an earlier state that is known to work. For a release, it means serving the previous build again, which moves code and leaves data where it is. In a database, the word names something narrower: undoing one open transaction.
How long does a rollback last?
Until a new release is shipped or promoted: the rolled-back state has no timer, and the act of rolling back takes as long as your drill measured. On some hosts automatic deploys stay off until then, because Vercel turns off auto-assignment of production domains after a rollback and a Render dashboard rollback disables autodeploys.
How does git rollback work?
In git, going back is done with git revert, which records new commits that reverse the effect of some earlier ones and keeps history. git reset changes which commit HEAD points to, and git’s own docs, in their example of undoing commits permanently, say not to do it if you have already given those commits to somebody else. Neither changes what a host is serving until a deploy runs; the sequence for a push to main belongs with branch protection.
What is another word for rollback?
Revert is the usual word for a commit, and change-management teams call the same document a backout plan. A restore is a different act: it brings back data from a backup rather than an earlier build.
If you have a working app built with these tools and need it ready for real customers, this is what we do.
Built it with AI. Now it has to hold up for real customers.
The Production Hardening Sprint takes the app you already have and builds the production foundation underneath it. Authentication and access rules, payments that stay consistent, error handling, monitoring, backups, automated tests and a documented handover. Our engineers work inside your existing codebase for ten working days. All 123 deliverables are included, and you get the evidence for each one.
See the Production Hardening Sprint →
$2,500 fixed price · 10 working days · One codebase