Skip to content
← All posts
AI & Automation · 5 min read

Blue-Green vs Rolling Deployments on AWS: Choosing the Right Zero-Downtime Strategy

Blue-green or rolling? The answer determines how fast you recover when production breaks ??? and most teams only decide after the first bad deploy.

Your last zero-downtime deployment isn't zero-downtime if it quietly serves errors to 20% of users while the old version drains. That's what rolling deployments do when they go wrong ??? and most teams don't find out until a customer does. The choice between blue-green and rolling isn't a configuration detail. It's a risk management decision that determines how fast you can recover when things break in production.

Blue-Green Deployments: Two Environments, One Traffic Switch

Blue-green deployment runs two identical environments ??? blue is live, green is staged with the new version. Traffic switches in a single atomic flip: a load balancer or DNS change points everything at green. Blue stays warm as your instant rollback. The mental model is simple, which is why it's easy to underestimate what it takes to actually operate.

The cost is real: you're paying for two production environments, at least during deployment windows. On AWS, this typically means two sets of ECS task sets, two Auto Scaling Groups, or two Elastic Beanstalk environments. For teams running lean infrastructure, that's a number worth calculating before committing.

The benefit is proportional. Rollback is one config change. If green is broken, flip back to blue. No partial states, no mixed versions handling concurrent requests, no debugging which pods are running what. The blast radius of a bad deploy is measured in seconds. For teams with paying customers or contractual uptime SLAs, that math resolves quickly.

Rolling Deployments: Gradual Rollout, Non-Obvious Failure Modes

Rolling deployments replace instances incrementally ??? typically 25% or 33% of capacity at a time, depending on your minimumHealthyPercent setting in ECS or your maxSurge and maxUnavailable values in Kubernetes. The appeal is cost: you never run more than 100% of your baseline infrastructure. New capacity comes up, old capacity goes down.

But rolling deployments have a quiet failure mode most teams underestimate: version skew. During the transition window, v1 and v2 are both handling requests simultaneously. If v2 introduces a database schema change, an API contract change, or different session behavior, users get non-deterministic results depending on which instance answers. This isn't theoretical ??? it's the category of bug that's impossible to reproduce locally and takes hours to diagnose in production.

Where Each Strategy Actually Breaks Down

Blue-green's failure mode is state. If your application holds in-memory sessions, sticky connections, or in-flight background jobs, cutting traffic atomically can orphan active requests. WebSocket connections don't drain gracefully across an ALB listener switch. Long-running background jobs mid-flight on blue get cut off the moment you flip. For stateless REST APIs, none of this matters. For anything with persistent connections, job queues, or session affinity, you need a deliberate drain window before the switch.

Rolling deployments break down when your code isn't forward-compatible with itself. Database migrations are the most common culprit. If your deploy runs an Alembic or Prisma migration before the new code is fully live, and that migration drops a column the old instances still reference, those instances start throwing errors against the updated schema. The fix ??? expand/contract migrations, feature flags, two-phase deploys ??? adds real complexity that most teams only implement after the first incident forces them to.

Choosing Based on What You Can't Afford to Lose

The question isn't which strategy is objectively better. It's which failure mode your team is equipped to handle ??? and which downtime cost you can actually absorb.

Blue-green is the right default when your application is stateless or you can manage connection draining explicitly, your cloud costs can accommodate a second environment even briefly, and rollback speed matters more than resource efficiency. SaaS products with paying customers, e-commerce platforms, and any system with uptime SLAs should start here. The infrastructure cost of running a second environment for 10 minutes during a deploy is trivially small compared to a 20-minute incident at 2am.

Rolling makes sense when your infrastructure budget is genuinely constrained, your application is stateless, your database changes are always backward-compatible, and your team has instrumented deployment health checks that trigger automatic rollback on error rate spikes. It's viable ??? but it demands more operational discipline from the engineering team, not less. The lower infrastructure cost comes with higher overhead to manage correctly.

Making It Work on AWS

For blue-green on ECS, AWS CodeDeploy handles the traffic shift natively. You define two target groups, CodeDeploy manages the ALB listener rules, and you configure a trafficRoutingConfig set to linear, canary, or all-at-once. Canary is the right default for most teams: shift 10% of traffic to green, monitor for five minutes, then complete the switch. You get the rollback safety of blue-green with a small validation window to catch regressions before they reach 100% of users.

For rolling on ECS, set minimumHealthyPercent: 100 and maximumPercent: 200 in your service definition if you want genuine zero-downtime ??? this forces ECS to bring up new tasks before terminating old ones. Set minimumHealthyPercent: 50 only if you're willing to trade downtime risk for faster deploys and lower surge costs.

GitHub Actions ties both approaches together cleanly. A deploy step that calls aws deploy create-deployment and blocks on aws deploy wait deployment-successful gives you a pipeline that fails visibly when a deployment rolls back. No silent failures. No green CI on a broken production deploy.

A significant portion of teams using cloud DevOps services in Pakistan and across South Asia are still deploying with docker pull and systemctl restart on a single EC2 instance ??? and treating 20-minute recovery windows as normal operations. The tooling to do this properly is mature, well-documented, and cheaper than the first incident it prevents. The real investment isn't infrastructure cost. It's deciding which failure mode you're designing against before production decides for you.

Tagsdevopsawsci-cddeploymentcloud infrastructure

Building something like this?

We are happy to talk it through, whether or not it turns into work.

Get in touch