Best Practices & Process

Rollback Strategies: Fast Recovery from Failed Deploys

Master deployment rollback strategies: blue-green, feature flags, and database-safe rollbacks. Recover from failed deploys in seconds with error tracking.

A bad deployment can cascade into a production incident in seconds—suddenly your error rate spikes, users can't log in, or data pipeline jobs start failing. The difference between a 5-minute recovery and a 5-hour outage often comes down to a well-planned deployment rollback strategy. Whether you're running containerized microservices or a monolith, having a reliable way to revert bad changes is not optional; it's foundational.

This post covers the three most effective deployment rollback strategies: blue-green deployments, feature flags, and database-safe rollbacks. You'll learn when to use each, how to detect when you need to roll back (watching error rates in your error tracking system), and how to make rollbacks boring—something you execute calmly when you notice a problem, not something you scramble to invent at 2 AM.

Detecting failure: Let your error tracker be your canary

Before you can roll back, you need to know something is broken. Releasing a change and watching server logs is too slow and too manual. A good error tracking system is your first line of defense.

Set up a dashboard in LightTrace that shows error rate, grouped by release or environment tag. Within seconds of a deploy, if error count jumps significantly—say, 10x baseline—you have a signal. Many teams wire this to an automated alert: if error count spikes in the first 10 minutes after a deploy, page the on-call engineer or automatically trigger a rollback.

Capture the release tag in your Sentry SDK configuration so every error is tagged with the version that produced it:

import sentry_sdk

sentry_sdk.init(
    dsn="https://<key>@light-trace.robomiri.com/1",
    release="v2.14.3",
    traces_sample_rate=0.1
)

Once the error spike appears, you have data: the exact stack trace, affected users, and whether the spike is in one service or across the stack. This transparency is what turns a blind rollback into a confident rollback.

Ship a release tag with every deploy. Use semantic versioning (v1.2.3) or a git commit hash—anything that uniquely identifies the version. When you see a spike in error rate aligned with that release, you know exactly what to roll back.

Blue-green deployments: Zero-downtime reversals

Blue-green is a deployment pattern where you run two identical production environments (blue and green) side by side. You deploy to the inactive one, test it, then flip traffic to it. If something goes wrong, you flip back to the old environment in seconds.

Here's the flow:

  1. Production is currently on Blue. Green is idle.
  2. Deploy your new code to Green. Run smoke tests.
  3. Flip your load balancer or router to send traffic to Green.
  4. Watch error rates, latency, and user complaints for 5–10 minutes.
  5. If all is well, keep it on Green. Blue is now cold standby.
  6. If disaster strikes, flip back to Blue (your old, proven environment) in under a minute.

The beauty of blue-green is that rolling back isn't a scary code operation—it's just a router configuration change. Most blue-green flips take under 30 seconds and require no server restart.

# Example with nginx: switch traffic by changing upstream
upstream backend_blue {
  server app-blue.internal:3000;
}

upstream backend_green {
  server app-green.internal:3000;
}

# Current active: blue
upstream backend {
  server app-blue.internal:3000;
}

server {
  listen 80;
  location / {
    proxy_pass http://backend;
  }
}

# To rollback: change "upstream backend" to point to backend_blue instead

Kubernetes users can achieve this with service label selectors and blue-green deployments via Helm or Kustomize. The key is: keep the old environment running for at least a few hours (or until the next deploy) so you have a hot standby.

The tradeoff: blue-green consumes 2x infrastructure resources while both environments are running. For many teams, the cost of two environments (or two replica sets) is worth the peace of mind.

Feature flags: Surgical rollback without redeploying

If blue-green feels heavy or you can't afford double infrastructure, feature flags give you a different kind of safety: you deploy the code, but gate the behavior behind a flag that's off by default.

When you flip that flag on (for 1% of users, then 10%, then 100%), you're doing a gradual rollout. If error rate spikes at 10%, you turn the flag off—no redeployment, no container restart. The bad code is still running, but it's not being called.

// Initialize Sentry in a React app pointing at LightTrace
import * as Sentry from "@sentry/react";

Sentry.init({
  dsn: "https://<key>@light-trace.robomiri.com/1",
  release: "v2.14.3",
  tracesSampleRate: 0.1,
});

// In your component:
const features = await fetch("/api/feature-flags").then(r => r.json());

if (features.newPaymentFlow) {
  return <NewPaymentFlow />;
} else {
  return <LegacyPaymentFlow />;
}

Feature flags trade infrastructure simplicity for operational overhead. You need a feature flag service (LaunchDarkly, Unleash, or a homegrown system) and a discipline to remove old flags so your codebase doesn't become a graveyard. But for high-risk changes, the ability to kill a feature server-side is worth it.

Don't use feature flags as a substitute for testing. They're a safety net for the 1% of bugs that slip through. Use them alongside your error budget and a good post-incident review process.

Database schema and data rollback strategies

Rolling back code is easy if your database schema hasn't changed. But if your deploy included a schema migration, a rollback gets complicated. You can't just flip back to old code if the new code wrote data in a format the old code doesn't understand.

Strategy 1: Backward-compatible migrations. Write migrations that add columns or tables without removing anything. The old code can ignore new columns; the new code can handle rows without new fields (with sensible defaults). You deploy code first, then run migrations. If code fails, you roll back the code, and the schema just sits there—no data loss.

Strategy 2: Dual-write during rollout. For major schema changes, write to both old and new schemas during a rollout window. New code writes to both; old code reads from the old schema. Once all deployed instances are on the new code, you can stop dual-writing. Rollback is simple: revert code, keep the old schema, and ignore the new one until you're sure.

Strategy 3: Schema versioning and client negotiation. Store a schema version with each row or request. New code can read and write any supported version. Old code reads its native version and fails gracefully on unknown versions. This is more overhead but gives you flexibility.

Avoid reversing migrations at 3 AM. It's tempting ("just DROP the column and re-create the old one"), but a failed migration can corrupt data. Instead, plan schema changes with small, reversible steps, and use tools like Flyway to version and track them.

Testing your rollback procedure

Rollback strategies are only useful if they actually work when you need them. Here's what to test:

  • Run a fake incident drill. Spin up a staging environment that mirrors prod. Deploy a bad change, detect the failure, and execute your rollback. Time it. Document the steps. Share with the team.
  • Verify data consistency. After a rollback, spot-check that user data wasn't corrupted. Write a query that counts rows before and after, or validates that critical fields are sane.
  • Test your feature flag kill switch. Flip the flag off, then on, in staging. Confirm that toggling doesn't cause race conditions or stale caches.

The team that practices rollback is the team that executes it calmly when it matters.

Keep a runbook for your most common rollback scenarios. A one-page doc with exact kubectl or Docker commands, feature flag steps, or blue-green flip instructions saves precious minutes when you're under pressure.

Post-rollback: Close the loop with error tracking

Once you've rolled back and stabilized, your error tracker gives you the data to understand what went wrong. Filter errors by release version and look for patterns. Was it a race condition in a specific code path? A subtle JSON schema mismatch? A dependency version incompatibility?

Pull the errors, grouped and sorted by frequency, into your error triage process. The goal is: never roll back the same bug twice. Each rollback is a chance to learn and improve your testing or code review process.

Then, fix the root cause, add a test case that would have caught it, and deploy again—this time with confidence.

Start tracking errors in minutes

Detect deployment failures in seconds and roll back with zero guesswork. Try LightTrace free—get a complete error trace, affected user info, and release-tagged errors the moment a bad deploy ships.

Rolling back fast isn't just about minimizing downtime; it's about building a system where you can deploy often without fear. With the right tools and runbooks, a rollback is just another operational procedure—routine, reversible, and forgettable in the best way.

Fix your next production error faster

Point any Sentry SDK at LightTrace — free up to 5,000 events/month.