Skip to content

Software Deployment Strategies

Two separate decisions are usually run together under the word “deployment”. The first is how a whole system is replaced — a programme-level question about risk, cost and how long two systems have to coexist. The second is how a running fleet moves from version N to version N+1 — a mechanical question about traffic and instances. This page covers both, in that order.

Every component is replaced at once. This gives the shortest path to full deployment and carries the highest risk: there is no partial state to learn from, support load arrives in a single spike, and rollback means restoring the previous system wholesale. It suits smaller systems, or organisations that can accept a maintenance window.

Components, modules or user populations are migrated in stages. Risk per stage is low and each stage informs the next, at the cost of a much longer overall timeline and a period during which old and new components must interoperate. It suits large or complex systems where a single cutover would be too disruptive.

Old and new systems run side by side for a period, often with the same inputs, so their outputs can be compared. It looks like the safest option and is the most expensive: two systems to operate, and a data synchronisation problem that is frequently underestimated. It suits systems where a wrong answer is worse than a slow migration — settlement, billing, clinical records.

AspectBig bangPhased rolloutParallel adoption
DefinitionComplete replacement in a single eventGradual implementation in stages or modulesOld and new run simultaneously for a period
Time to full deploymentShortLongMedium to long
Risk levelHighLow to mediumMedium
Disruption to operationsHighLowLow to medium
Resource requirementsHigh, short-termMedium, spread outHigh — two systems to maintain
Rollback difficultyVery difficultEasyEasy
User adaptationChallenging — sudden changeEasier — gradual changeModerate — users can compare
TestingMust be exhaustive before cutoverEach phase tested separatelyCan be tested while the old system still runs
CostLower upfront, higher if it goes wrongHigher, from the longer timelineHigher, from running two systems
Best suited toSmaller or less critical systemsLarge, complex systemsSystems where failure is not an option
StrategyPrincipal risksMitigations
Big bangSystem-wide failure; support demand exceeding capacity; data migration defects; unforeseen integration problemsExhaustive pre-cutover testing; user training before the date; a written and rehearsed rollback plan; all-hands support during the transition
Phased rolloutExtended timeline; compatibility between old and new components; user confusion from partial functionalityPublish the rollout plan; design the interfaces between old and new deliberately; train each population as its phase arrives
Parallel adoptionData divergence between the two systems; higher running cost; reluctance to move off the old systemRobust synchronisation and reconciliation; a fixed date for decommissioning the old system; make the new system the only route to new functionality

In practice most programmes use a hybrid: a phased rollout by region or customer segment, with parallel running for the components where divergence would be expensive.

These four patterns describe how a specific service moves from one version to the next. They compose with the programme-level strategies above rather than competing with them.

AspectRollingA/B testingCanaryBlue-green
DefinitionReplace instances of the old version with the new one, in batchesRoute a share of traffic to a new version to compare behaviourRelease to a small subset before full deploymentTwo identical environments; switch traffic from one to the other
Traffic distributionShifts as instances are replacedSplit between two versionsSmall share first, then increasedFull switch
RiskMediumLowLowLow to medium
RollbackModerate — redeploy the old versionEasy — change the weightsEasy — shift traffic backVery easy — switch back
CostLowMediumLow to mediumHigh — two full environments
DowntimeMinimal to noneNoneNoneNone, done correctly
User impactMinimalSome users see a different versionLimited initiallyNone, done correctly
Testing in productionLimitedYesYesLimited
Principal AWS servicesAuto Scaling groups, Elastic Load BalancingRoute 53, CloudFront, API GatewayAuto Scaling groups, Application Load Balancer, CodeDeployRoute 53, Elastic Load Balancing, Elastic Beanstalk

Instances in an Auto Scaling group are replaced in batches until the whole fleet runs the new version.

  1. Create a new version of the group’s launch template carrying the updated AMI or user data, and set it as the group’s launch template version. Launch configurations are the older mechanism and are no longer an option: new EC2 instance types have not been supported in them since 1 January 2023, and accounts created on or after 1 October 2024 cannot create one by console, API, CLI or CloudFormation.
  2. Start an instance refresh, or terminate old instances in batches.
  3. Auto Scaling launches replacements from the new launch template version.
  4. The load balancer keeps traffic on instances that pass health checks, so capacity is maintained throughout.

The fleet runs mixed versions for the duration, so the two versions must be able to coexist — same database schema, compatible session handling, compatible API contracts.

Two versions run concurrently and traffic is split between them so their behaviour can be compared on real users. Route 53 weighted routing is the simplest mechanism: two record sets for the same name with weights of, say, 90 and 10, adjusted as confidence grows. CloudFront with Lambda@Edge or CloudFront Functions supports finer-grained routing on headers or cookies, and API Gateway stage variables can point the same route at different backend versions.

A/B testing is a measurement technique that happens to require two versions in production. It is not, by itself, a safe-release mechanism.

A small proportion of traffic goes to the new version, the release is watched for a defined period, and the proportion is increased only if the error and latency metrics hold. An Application Load Balancer with weighted target groups does this for EC2 and ECS; CodeDeploy does it natively for Lambda aliases and ECS services, with automatic rollback wired to a CloudWatch alarm. API Gateway REST APIs have a built-in canary release setting per stage.

The value of a canary comes from the automated abort condition. Without an alarm that stops and reverses the rollout, it is just a slow deployment.

Two complete environments exist: blue is the current version, green is the new one. Traffic is switched from blue to green in one step once green is verified, and switched back if it is not. The goal is immutable infrastructure — the deployed application is never modified in place, it is replaced.

Ways to make the switch on AWS:

  1. DNS-based switching with Route 53 record sets.
  2. Replacing the Auto Scaling group behind a load balancer, or moving the listener to a new target group.
  3. A new launch template version, deployed to a new Auto Scaling group.
  4. Elastic Beanstalk’s swap-environment-URLs operation.
  5. A CodeDeploy blue-green deployment group, for EC2/Auto Scaling, Amazon ECS or Lambda.

Advantages: no in-place mutation, one-step rollback, zero downtime, and the ability to keep the old environment available for as long as the risk warrants.

DNS-based switching has one caveat worth stating plainly: clients and resolvers cache DNS, so “instant” rollback is bounded by the record’s TTL and by resolvers that ignore it. Where a rollback has to be genuinely immediate, switch at the load balancer rather than at DNS.

Tightly coupled data schemas. If the application version and the database schema must match, blue and green cannot share a database, and rollback means rolling the schema back too. The fix is to make schema changes forward and backward compatible — expand, migrate, contract — so both versions can run against the same schema.

Special upgrade routines. Applications that need a migration step, a post-processing job or a licence re-registration cannot be switched by repointing traffic. Rollback becomes more than a DNS change, and the strategy loses its main advantage.

Off-the-shelf products. Some commercial software cannot run two instances against one data store, or licenses per installation. Confirm with the vendor before designing around it.

Keep the data layer independent. The looser the coupling between application version and schema version, the more deployment options remain open. Version the schema, and make every migration compatible with the release either side of it.

Define the abort condition before the release. Error rate, latency percentile and business metric, with a threshold and a duration. A deployment that nobody is prepared to stop is not being monitored, it is being watched.

Rehearse the rollback. Test it in a non-production environment on the same mechanism production will use. An untested rollback plan is a hypothesis.

Account for the extra capacity. Rolling with an additional batch, immutable and blue-green deployments all run more instances than steady state for the duration. Confirm the account’s service quotas allow it before the release, not during it.

Related material: Auto Scaling groups for launch templates, scaling policies, health checks and lifecycle hooks; Elastic Beanstalk for the deployment options a managed platform offers out of the box.