Skip to content
New: managed cloud and dedicated servers — with dedicated support on every plan.See plans
Inventure Technologies

Zero-downtime deployments: blue-green, rolling and canary explained

How to achieve zero downtime deployment with blue-green, rolling and canary strategies, health checks, database migrations and a working nginx example.

IInventure Engineering Team6 min read
On this page

A zero-downtime deployment ships new code to production without dropping traffic or breaking active user sessions, by never taking all your serving capacity offline at the same time. Blue-green, rolling and canary are the three common ways to achieve this, and they trade off differently on blast radius, rollback speed and how much infrastructure they need. This post explains each, plus the health checks, database migration pattern and feature flags that make any of them actually safe.

For where this fits into a wider release process, see the pillar guide: DevOps as a service: what it is, what it costs, and when it beats hiring.

Why deployments cause downtime in the first place#

The naive deployment — stop the old version, start the new one — has a gap in the middle where nothing is listening. Even without that gap, two subtler problems cause the same symptom: a load balancer keeps sending requests to an instance that's mid-restart, and in-flight requests get cut off when a process exits before finishing them. A third cause is a database schema change that breaks whichever code version happens to still be running during the switch. Every strategy below exists to remove one or more of these gaps.

Blue-green deployments#

Blue-green deployment keeps two identical production environments — call them blue and yesterday's green — with only one live at a time. You deploy the new version to the idle environment, test it against real infrastructure with no live traffic, then switch a router or load balancer so all traffic goes to it at once. The other environment stays idle as an immediate rollback target: if something's wrong, you switch back.

Rolling deployments#

A rolling deployment replaces instances of the old version with the new one a few at a time, rather than switching everything at once. Kubernetes' Deployment controller does this by default: maxSurge controls how many extra Pods beyond the desired count can exist during the rollout (default 25%), and maxUnavailable controls how many can be offline at once (also 25% by default). It creates a new ReplicaSet and scales it up while scaling the old one down at a rate governed by those two settings — no second full environment required, but for a period, both versions serve traffic simultaneously. You don't need Kubernetes to do this: the same idea works with a handful of application instances behind any load balancer, taking one out of rotation, updating it, and confirming it's healthy before moving to the next. See do you really need Kubernetes? if you're weighing up whether the automation is worth adopting yet, and Docker to production for the container and healthcheck setup a rolling deployment relies on either way.

Canary deployments#

A canary release shifts a small percentage of traffic to the new version first, watches it, and only proceeds if it looks healthy. Flagger, a Kubernetes progressive-delivery tool, describes the pattern as increasing traffic in small steps (for example, 2% at a time) up to a maximum weight, gated at every step on metrics like HTTP success rate and latency; if any check fails, all traffic reverts to the stable version automatically. This gives the smallest blast radius of the three, at the cost of needing traffic-splitting infrastructure and defined success metrics to check against.

Comparing the three#

Strategy

Infrastructure needed

Rollback speed

Blast radius if something's wrong

Blue-green

Two full environments, at least temporarily

Fast — switch traffic back to the environment still running

All-or-nothing: either fully old or fully new

Rolling

One environment; replaces instances gradually

Slower — rolling back is another gradual rollout

Partial: some users hit the new version during the rollout

Canary

One environment plus traffic-splitting and metrics

Fast — revert the traffic split

Smallest: only a small, controlled slice of users see it first

Which zero downtime deployment strategy should you actually use?#

Most teams don't need to pick permanently. Blue-green is the easiest to reason about and a natural starting point if your infrastructure can afford two environments, even briefly — it's simple enough to implement with the nginx example below on plain servers. Rolling suits teams already running several instances behind a load balancer or on Kubernetes, since it needs no extra environment and is often the default your platform already gives you. Canary is worth the extra setup once a bad release has a high enough cost — real revenue, a large user base, or a change risky enough that you want live production signal before committing everyone to it. It's also reasonable to combine them: a canary step to catch an obviously broken release early, followed by a rolling or blue-green rollout for the rest of the traffic.

Health checks and connection draining#

None of these strategies is safe without two supporting mechanics. First, something has to know an instance is actually ready before sending it traffic, and stop sending traffic the moment it isn't — in Kubernetes terms, a readiness probe failing removes a Pod from Service endpoints without killing it, while a liveness probe failing restarts the container. Second, when an instance is being removed, in-flight requests need time to finish rather than being cut off — on an AWS Application Load Balancer this is the deregistration delay, 300 seconds by default and configurable up to an hour, during which a draining target stops receiving new requests but finishes ones already in progress.

Expand/contract migrations for the database#

Application code is easy to run two versions of at once; a database schema often isn't, since both old and new code may need to query it during a rolling release. The expand/contract pattern (also called parallel change) solves this in three phases: expand — add the new column, table or field alongside the old one, so both exist together; migrate — move code and data over to the new structure, which can happen gradually or take a while; contract — remove the old structure once nothing references it any more. Each phase is independently deployable, which is exactly what a rolling or canary release needs.

Feature flags: decoupling deploy from release#

A feature toggle is a runtime switch that changes behaviour without a new deployment. This matters for zero-downtime releases because it separates two things that are often conflated: deploying code (getting it running in production) and releasing a feature (turning it on for users). You can deploy new code dark, behind a flag, verify it's stable under real production conditions, then flip it on — and if something's wrong, turn it off instantly, without waiting for a rollback deployment to roll out.

Rolling back safely#

Treat rollback as a rehearsed path, not a last resort you figure out during an incident. Blue-green rollback is normally fastest, since the previous environment is still running and just needs traffic pointed back at it. Rolling rollback takes roughly as long as the original rollout, since it's the same gradual process in reverse. Whatever the strategy, a rollback that depends on a database migration having a working reverse path is the part most often forgotten — the expand/contract pattern above is partly what makes rollback safe, since the old code path still works during the migrate phase.

A simple blue-green example with nginx#

One way to implement blue-green on plain servers is to keep two upstream definitions and switch which one an active config file points to, then reload nginx — which reloads workers gracefully, finishing in-flight requests on the old configuration before it's fully replaced.

nginx
# upstream_blue.conf
upstream app {
    server 10.0.1.10:3000;
    server 10.0.1.11:3000;
}
nginx
# upstream_green.conf
upstream app {
    server 10.0.2.10:3000;
    server 10.0.2.11:3000;
}
nginx
# nginx.conf (unchanged across switches)
include /etc/nginx/conf.d/active_upstream.conf;

server {
    listen 80;

    location / {
        proxy_pass http://app;
    }
}

Switching from blue to green is then a symlink swap plus a reload, not a config rewrite:

bash
ln -sf /etc/nginx/conf.d/upstream_green.conf /etc/nginx/conf.d/active_upstream.conf
nginx -t && nginx -s reload

nginx -t validates the new configuration before it's live, and -s reload starts new worker processes on the new config while letting existing workers finish their current requests — so the switch itself doesn't drop traffic. Rolling back is the same command pointed at upstream_blue.conf.

What to do next#

Picking the right strategy matters less than actually rehearsing it before you need it under pressure — a rollback you've never tested is a rollback you can't trust during an incident. CI/CD automation covers wiring a deployment strategy like this into your pipeline, and managed DevOps covers having someone accountable for it running correctly release after release.

Frequently asked questions

What's the difference between blue-green and canary deployment?

Blue-green switches all traffic at once between two complete environments, so it's all-or-nothing but easy to reason about and fast to roll back. Canary shifts a small percentage of traffic to the new version first, checks metrics, and gradually increases it — smaller blast radius if something's wrong, but more moving parts to set up.

Do I need Kubernetes to do rolling deployments?

No. Kubernetes automates rolling updates for you, but the underlying idea — replace old instances with new ones a few at a time, behind a load balancer or reverse proxy — works on plain servers too. See do you really need Kubernetes? if you're deciding whether the automation is worth the added complexity yet.

What is an expand/contract migration?

A three-phase pattern for changing a database schema without downtime: expand (add the new column or table alongside the old one), migrate (move code and data over, which can take time), then contract (remove the old structure once nothing uses it). It works because both old and new code can run at the same time during a rolling release.

How do feature flags relate to zero-downtime deployment?

They separate two different actions that are often bundled together: deploying code to production, and turning a feature on for users. With a flag, you can deploy new code dark (switched off), verify it's stable, then enable it — and disable it instantly if something's wrong, without a rollback deployment.

How fast should a rollback be?

As fast as your deployment strategy allows, ideally under a few minutes. Blue-green rollback is typically fastest, since it's just switching traffic back to the environment that was already running moments before. Rolling rollback takes about as long as the original rollout. This is one reason to rehearse rollbacks, not just deployments.

Sources

  1. BlueGreenDeployment — Martin Fowler — accessed 18 September 2026
  2. Deployments (RollingUpdate strategy) — Kubernetes Documentation — accessed 18 September 2026
  3. Deployment Strategies (canary) — Flagger Documentation — accessed 18 September 2026
  4. Module ngx_http_upstream_module — NGINX Documentation — accessed 18 September 2026
  5. ParallelChange — Martin Fowler — accessed 18 September 2026
  6. FeatureToggle — Martin Fowler — accessed 18 September 2026
  7. Pod Lifecycle (readiness and liveness probes) — Kubernetes Documentation — accessed 18 September 2026
  8. Edit target group attributes (deregistration delay) — AWS Documentation — accessed 18 September 2026

Facts in this article were last checked on 18 September 2026.

I

Inventure Engineering Team

Engineers at Inventure Technologies who build, host and run software for clients in Nepal and Australia. We write about what we do every day.

Keep reading

Want engineers who handle this for you?

We build, host and run software for teams in Nepal and Australia — with dedicated support on every plan.