Blog
4 min read

Blue-Green vs Canary vs Rolling Deployments

Three ways to release a new version without taking your app down or betting everything on it working. How blue-green, canary and rolling deployments work, what each needs, how they handle database migrations, and a pragmatic approach for a small app on one or two servers.

The naive deploy — stop the old version, start the new one — causes a few seconds (or minutes) of errors, and if the new version is broken, every user sees it immediately. Deployment strategies fix both problems in different ways. (Zero-downtime deploys)

Rolling deployment

Replace instances one (or a few) at a time. With four instances, update one, wait until it's healthy, then the next.

  • ✅ No extra servers needed; no downtime if you have more than one instance.
  • ❌ Old and new versions run side by side during the rollout, so they must be compatible.
  • ❌ Rolling back means rolling forward again with the old version.

The default in Kubernetes, Docker Swarm and many platforms. (Do you need Kubernetes?)

Blue-green deployment

Run two complete environments:

  • Blue — the live version, getting all traffic.
  • Green — the new version, deployed and tested while getting no real traffic.

When green passes its checks, switch the load balancer or proxy to green, all at once. Blue stays running, untouched.

          ┌─ blue (v1)   ← traffic
proxy ────┤
          └─ green (v2)  ← deploy and test here, then switch
  • ✅ Instant rollback: switch back to blue.
  • ✅ Test the new version in production conditions before users see it.
  • ❌ Needs capacity for two full environments (briefly).
  • ❌ All users switch at once — a bug not caught by tests hits everyone.

Canary deployment

Send a small percentage of traffic to the new version — 1%, then 5%, 25%, 100% — while watching error rates and latency. If metrics look bad, send everyone back to the old version.

  • ✅ A bad release affects only a few users, briefly.
  • ✅ Catches problems tests miss, using real traffic.
  • ❌ Needs traffic splitting and good monitoring to decide automatically or quickly. (What is OpenTelemetry?, Error monitoring)
  • ❌ Needs enough traffic for small percentages to be meaningful.

Named after canaries in coal mines.

Side by side

Rolling Blue-green Canary
Extra capacity Little 2× briefly A little
Rollback speed Slow (redeploy) Instant Fast
Blast radius of a bug Grows during rollout Everyone at switch Small, controlled
Old + new run together Yes Briefly Yes, for the whole rollout
Complexity Low Medium Higher (needs metrics)

The hard part: the database

All three strategies share one database, and in rolling and canary deploys both versions use it at the same time. So schema changes must be backward compatible:

  1. Expand — add new columns/tables; don't remove or rename anything the old version uses.
  2. Deploy the new code, which works with the expanded schema.
  3. Migrate data if needed.
  4. Contract — in a later deploy, remove what the old version needed.

Renaming a column in one step breaks whichever version doesn't expect it. (Postgres migrations on large tables, Prisma migrations in production)

Feature flags: a different lever

Feature flags separate deploying code from releasing features: ship code turned off, then enable it for 1% of users, then everyone. Canary-like control at the feature level, without traffic routing. (Feature flags)

For a small app on one server

You don't need Kubernetes for most of this:

That covers most of the benefit with very little machinery.


EasySpawn gives every branch a live preview URL on your server and runs production behind a reverse proxy with health checks — the building blocks for safe releases without a platform team. See how it works or join the waitlist.

Related: Zero-Downtime Deploys for a Small App · Feature Flags for Small Teams · Preview Environments for Every Branch · Health Check Endpoints

Keep reading