Blue-Green Deployments in Kubernetes

Blue-Green Deployments in Kubernetes

Learn how to ship a new version of your application by building it beside the old one, testing it in private, and moving users across with a single switch, and how to move them back just as fast if something goes wrong.

Picture a theatre with two identical stages standing side by side. The audience is watching a play on stage one. Behind the curtain of stage two, the crew is quietly building the set for the next play, rehearsing every scene, and checking every light. When everything is perfect, the crew swings one big spotlight from stage one to stage two, and the audience sees the new play instantly, with no pause and no half-built scenery.

If the new play turns out to have a problem, the spotlight swings back in a heartbeat, because the old stage was never taken apart. That is the whole idea behind a blue-green deployment. This tutorial explains how to build that theatre inside Kubernetes, how it works under the hood, where it can hurt you, and how teams run it safely in production.

1Why Releasing Software Is Risky

Before we talk about blue and green, we need to understand the problem they solve: putting new software in front of real users without breaking anything.

What does “deploying” mean?

An application is a program that people use, such as a shopping website or a banking app. Developers keep changing it by fixing bugs, adding features, and making it faster. Each time a new version is ready, it must be placed on the servers where real users can reach it. That step is called a deployment, and the place where real users live is called production.

In Kubernetes, applications run inside containers. A container is a small sealed package that holds your program and everything it needs, so it behaves the same on every computer. Kubernetes is a system that runs many containers across many computers and keeps them healthy. A deployment in Kubernetes therefore means telling the cluster, which is the group of computers Kubernetes manages, to start running the new version of your containers.

Why is deploying risky?

A new version can behave very differently in production than it did on a developer’s laptop. Real users send strange inputs, real databases hold messy old data, and real traffic is far heavier than any test. Some bugs simply cannot be seen until the code meets these real conditions.

There are two costs to worry about. The first is downtime, the period when users cannot use the application at all. The second is what we can call bad time, when the application is technically running but giving errors or wrong answers. Bad time is often worse than downtime, because it can quietly corrupt data, charge customers twice, or show private information to the wrong person.

Every deployment strategy is really an answer to two questions. How do we keep users happy while we change things? And how quickly can we undo the change if we made a mistake? The ability to undo a change is called a rollback, and a good strategy makes rollback cheap, fast, and boring.

Simple Analogy

Imagine a busy bridge that needs repainting. You could close the whole bridge for a week, which is downtime. You could paint one lane at a time while cars squeeze past, which is slow and messy. Or you could build a second identical bridge beside it, paint it in peace, and then move all the traffic over in one go. Blue-green deployment is the third option.

A quick map of deployment strategies

Blue-green is one of several ways to release software. Knowing the others helps you understand why blue-green exists and when it is the right tool. Here are the main strategies you will meet in Kubernetes work.

Strategy 1

Recreate

Stop every old instance, then start the new ones. Simple, but users see downtime between the two steps.

Strategy 2

Rolling Update

Replace old instances with new ones a few at a time, so capacity never drops to zero. This is the Kubernetes default.

Strategy 3

Blue-Green

Run two full environments. Test the new one privately, then switch all traffic at once. Roll back by switching again.

Strategy 4

Canary

Send a small slice of real traffic, such as five percent, to the new version first, and grow the slice if all looks healthy.

Strategy 5

Shadow (Mirroring)

Copy live requests to the new version but throw away its answers, so it is tested with real traffic without affecting users.

Strategy 6

A/B Testing

Show different versions to different groups on purpose to measure which one performs better for the business.

i
Deploy is not the same as release

Deploying means the new code is running somewhere. Releasing means real users can reach it. Blue-green separates these two moments cleanly: you deploy to the idle environment hours before you release to users, and the release itself is just a switch.

2Blue-Green Deployment: The Core Idea

Two identical environments, one live and one idle, with a switch that decides which one users see.

The idea in plain words

In a blue-green deployment you always keep two copies of your production environment. One copy, the live one, serves all user traffic. The other copy sits idle and is called the standby. When you want to release a new version, you install it on the idle copy, test it thoroughly without any user seeing it, and then flip a switch so that users are sent to the new copy instead.

After the flip, the roles are reversed. The copy that just received the new version is now live, and the old copy becomes the standby. You leave the old copy running for a while, untouched, as your safety net. If the new version misbehaves, you flip the switch back and users return to the version that was working a moment ago.

Simple Analogy

Think of a railway with two identical tracks and a lever that moves the points. The train, which is your user traffic, is running on track A. Workers spend the afternoon upgrading track B and test-driving an empty engine along it. When track B is proven safe, one pull of the lever sends the train onto it. If a problem shows up, the lever is pulled back and the train returns to track A.

Where do the names come from?

The colours are just labels. The pattern is usually credited to Dan North and Jez Humble, who described it while working at ThoughtWorks, and it was spread widely through Jez Humble and Dave Farley’s book on continuous delivery and through writing by Martin Fowler. Blue and green were chosen because they are neutral. Neither colour says “old” or “bad”, which matters because the roles swap every release.

Some organisations use different names for the same idea. Netflix, for example, has described a very similar approach using the words red and black in its Spinnaker delivery platform. The names do not matter. What matters is the shape of the idea: two full environments and a controlled switch between them.

2
identical environments kept ready
1
switch decides who sees which version
Seconds
typical rollback time while the old version still runs

The vocabulary you will use

Term 1

Blue Environment

One of the two copies. In one release it may be live; in the next it may be the idle standby.

Term 2

Green Environment

The other copy. It is the twin of blue, running the same infrastructure but possibly a different application version.

Term 3

Traffic Switch

The single point that decides where user requests go. In Kubernetes this is a Service, an Ingress, a mesh route, or a controller.

Term 4

Cutover

The moment the switch is flipped and users start arriving at the new environment.

Term 5

Rollback

Flipping the switch back to the previous environment after a bad release.

Term 6

Smoke Test

A short set of quick checks that proves the most important features work, such as logging in and placing an order.

Term 7

Warm-up

Getting a fresh environment ready for real load by filling caches, opening database connections, and starting runtimes.

Term 8

Soak Period

The waiting time after cutover when you watch the new version closely before deleting the old one.

“Blue-green turns a risky release into a reversible decision.”
i
Colours swap every release

Do not think of blue as production and green as staging. Whichever colour is idle is simply the next target. If blue is live today, tomorrow’s release goes to green, and the release after that goes back to blue.

3Kubernetes Building Blocks You Need First

Blue-green in Kubernetes is built from a handful of ordinary objects, so let us meet each one before we combine them.

Kubernetes does not have a button labelled blue-green. Instead, it gives you a small set of building blocks, and clever teams combine them to get the behaviour. Understanding each block on its own makes the later chapters feel obvious rather than magical.

Block 1

Container

A sealed package holding your program and everything it needs, so it behaves the same on every computer.

Block 2

Pod

The smallest unit Kubernetes runs. A pod wraps one or more containers that share a network address and live and die together.

Block 3

ReplicaSet

A supervisor that keeps a fixed number of identical pods running. If one crashes, it starts a replacement.

Block 4

Deployment

A manager that owns ReplicaSets and knows how to move from one version of your application to the next.

Block 5

Service

A stable address and name in front of a changing group of pods. Clients talk to the Service, and the Service picks a healthy pod.

Block 6

Label and Selector

Labels are name tags on objects. A selector is a question such as “find everything tagged with the green version”.

Block 7

EndpointSlice

The live list of pod addresses that currently match a Service and are ready. Kubernetes keeps it up to date automatically.

Block 8

Ingress

A front door for outside traffic. It reads the web address and path of each request and sends it to the right Service.

Block 9

Readiness Probe

A small health check that tells Kubernetes when a pod is truly ready to receive user requests.

Block 10

Namespace

A named room inside the cluster used to group and separate resources, such as one team’s or one environment’s.

Labels and selectors: the secret ingredient

If you remember only one thing from this chapter, remember labels and selectors. A label is a small key and value pair, such as “version: green”, attached to a pod. A selector is a rule that picks objects by their labels. The link between a Service and its pods is not a fixed list of addresses. It is simply a selector saying “send traffic to every ready pod carrying these labels”.

This loose connection is exactly what makes blue-green possible. If the Service’s selector can be changed from “blue” to “green”, then the very same Service, with the very same address, starts sending traffic to a completely different set of pods. Nothing else about the clients needs to change.

Simple Analogy

Picture a conference where every attendee wears a coloured lanyard. The reception desk announces, “Send all visitors to the people wearing blue lanyards.” Later the desk changes the announcement to green lanyards. The visitors keep coming to the same reception desk, but they are now guided to a different group of people. The desk is the Service, the lanyards are labels, and the announcement is the selector.

Service: a phone number that never changes

Pods are temporary. They are created, destroyed, and moved between computers all the time, and each new pod gets a new network address. If clients had to remember pod addresses, they would break constantly. A Service solves this by giving your application one stable name and one stable virtual address that never changes, no matter how many pods come and go behind it.

i
Why this matters

Because clients only know the Service, you can replace every pod behind it without telling anyone. Blue-green simply replaces the whole group at once instead of one pod at a time.

Readiness and liveness: are you open, and are you alive?

Kubernetes uses two different health checks. A liveness probe asks, “Is this pod still alive, or is it stuck?” If the answer is no, Kubernetes restarts it. A readiness probe asks, “Is this pod ready to serve users right now?” If the answer is no, Kubernetes keeps the pod running but stops sending it traffic.

Readiness is the one that matters most for blue-green. A pod may take thirty seconds to load data or connect to a database. During that time it is alive but not ready, and it must not receive user requests. The Service only sends traffic to pods that are ready, so a good readiness probe is what guarantees that green is truly prepared before it ever meets a user.

Simple Analogy

A restaurant can have a chef who is alive and in the building but still tying his apron and heating the ovens. The “Open” sign on the door is the readiness probe. Customers are only let in when the sign flips to open, even though the chef was alive the whole time.

!
Common mistake

Skipping the readiness probe, or writing one that always says yes. Without an honest readiness check, Kubernetes will happily send users to a green pod that is still starting up, and your smooth switch becomes a burst of errors.

4What Kubernetes Does by Default

Kubernetes ships with two built-in update styles, and neither is blue-green. Seeing why makes it clear what we have to add ourselves.

Rolling update: the default

When you change the container image in a Deployment, Kubernetes performs a rolling update. It creates a few new pods, waits for them to become ready, removes a few old pods, and repeats until every pod runs the new version. Two settings control the pace. One says how many extra pods may exist temporarily, and the other says how many pods may be unavailable at any moment.

Rolling updates are efficient because they need very little extra capacity, and users usually notice nothing. The downside is that for a while both versions serve real users at the same time, mixed together, and you cannot test the new version privately first. Undoing the change is also a second rolling update, which takes as long as the first one.

Simple Analogy

A rolling update is like replacing the staff of a shop one person at a time. The shop never closes, but for a while customers are served by a mix of old and new staff, and if the new staff turn out to be a bad hire, swapping everyone back takes just as long as swapping them in.

Recreate: the blunt option

The recreate strategy deletes all old pods first and only then starts the new ones. It is easy to understand and guarantees that two versions never run together, which can matter if the old and new versions cannot share a database. The price is downtime, from the moment the old pods stop until the new pods are ready.

Why blue-green is not built in

A Kubernetes Deployment thinks about one journey at a time, from the current version to the next version, one step after another. It has no idea that you might want two complete, fully running environments side by side and a single atomic switch between them. There is also no built-in object called a “traffic switch” that moves every user at once and can be undone instantly.

To get blue-green, we compose it from parts that already exist, such as two Deployments and a Service, or we install an extra controller that automates the choreography. The following chapters cover both approaches. First, here is how the three strategies compare side by side.

AspectRecreateRolling UpdateBlue-Green
DowntimeYes, between stop and startNormally noneNormally none
Extra capacity neededNoneA littleA full second copy, at least temporarily
Two versions serving users togetherNoYes, during the rolloutBriefly at the switch, otherwise no
Private testing before users arriveNoLimitedYes, full testing on the idle side
Rollback speedSlow, redeploy the old versionSlow, another rolling updateFast, flip the switch back
Built into KubernetesYesYesNo, composed or added with a controller
!
Common misconception

Many people believe that a rolling update with a rollback command is “the same as blue-green”. It is not. A rolling rollback has to create and warm up old pods all over again, while a blue-green rollback moves traffic to pods that are already running and warm.

5Architecture: Ways to Build Blue-Green in Kubernetes

There is no single official recipe. Teams use five common patterns, ranging from the simplest trick in core Kubernetes to a fully automated platform.

All five patterns share the same skeleton. There are two groups of pods, blue and green, each managed by its own Deployment. Above them sits a traffic switch that decides who receives user requests. Below them sit shared dependencies such as a database, a cache, or a message queue. The figure below shows this skeleton.

flowchart LR
    U["Users"] --> S["Traffic switch: Service or Ingress"]
    S -->|"100 percent live"| B["Blue pods: version 1"]
    S -.->|"0 percent until cutover"| G["Green pods: version 2"]
    B --> D[("Shared database")]
    G --> D
        
FIG 1 — The blue-green skeleton: one switch, two pod groups, one shared database

Read the figure from left to right. Users always talk to the traffic switch and never to blue or green directly. The solid arrow shows the live path, where every request goes to blue. The dotted arrow shows the waiting path, where green is running but receives nothing. Notice that both colours point at the same database. That shared dependency is the hardest part of blue-green, and Chapter 8 is devoted to it.

The components you will run

Component 1

Blue Deployment

Manages the pods of one environment, with a colour label so they can be selected as a group.

Component 2

Green Deployment

Manages the twin environment. It is created from the same template with only the version and colour changed.

Component 3

Live Service

The stable address that real users reach. Its target is the thing you flip during cutover.

Component 4

Preview Service

A second address that always points at the idle colour, so testers can reach it without touching live traffic.

Component 5

Traffic Router

The Ingress, Gateway, or mesh route that sits in front of the Services and applies routing rules.

Component 6

Shared Configuration

ConfigMaps and Secrets that both colours read. They must be compatible with both versions.

Component 7

Delivery Pipeline

The automation that builds the image, deploys to the idle colour, runs tests, and triggers the switch.

Component 8

Observability Stack

Metrics, logs, and traces that let you compare blue and green and decide whether the release is healthy.

Pattern 1: Two Deployments and one Service

This is the simplest pattern and needs nothing beyond core Kubernetes. You create one Deployment whose pods carry the label “blue” and another whose pods carry the label “green”. A single Service selects pods using the application name plus a colour label. To cut over, you edit the Service so that its colour selector reads green instead of blue.

The strengths are simplicity and transparency, because anyone who knows Services can understand it. The limits are that the switch is strictly all or nothing, there is no built-in gradual shift, and a separate preview Service is needed so testers can reach the idle colour. You also have to make sure the two Deployment definitions do not slowly drift apart.

Simple Analogy

This pattern is like call forwarding on a phone. Customers always dial the same number, which is the Service. You simply change where the calls ring, from the blue office to the green office, and the customers never notice anything except that the person answering now knows the new product line.

Pattern 2: Switching at the Ingress or Gateway

Here you keep two Services, one for blue and one for green, and you change which Service the Ingress or Gateway sends traffic to. Because the switch happens at the web layer, you can make richer decisions. For example, you can send everyone to blue but send requests carrying a special test header to green, which lets your testers use the real public address while ordinary users are unaffected.

The Gateway API is the newer standard for describing this kind of routing, and it supports weighted backends directly. The limit is that the exact features depend on which ingress controller you run, and older Ingress objects often rely on controller-specific annotations that are not portable.

Pattern 3: Routing with a service mesh

A service mesh, such as Istio or Linkerd, places small proxies next to your pods and controls every request between services. A routing rule in the mesh can say “send one hundred percent to blue and zero to green”, and flipping the numbers performs the cutover. The mesh can also route by header for private testing, retry failed calls, and encrypt traffic between pods.

The cost is complexity and extra resource use, because you now operate the mesh as well. A useful side effect is that once you have weights, you can shift from blue-green toward canary by choosing values like ninety and ten instead of one hundred and zero.

Pattern 4: A progressive delivery controller

Tools such as Argo Rollouts and Flagger automate the choreography. Argo Rollouts replaces the ordinary Deployment with a Rollout object that has a blue-green strategy built in. It starts the new ReplicaSet, points a preview Service at it, waits for approval or for automatic checks to pass, promotes it by moving the active Service, and scales the old ReplicaSet down after a delay you choose. Flagger works on top of a mesh or ingress controller and automates similar progressive release flows using metrics.

The benefit is that the release becomes a repeatable, observable process instead of a series of manual edits. The cost is one more component to install, learn, secure, and keep upgraded.

Simple Analogy

A controller is like an autopilot on an aircraft. The pilot chooses the destination and the rules, such as “abort if turbulence is too high”, and the autopilot performs the many small steps in the right order, every single time, without getting tired or forgetting one.

Pattern 5: Whole-cluster blue-green

Sometimes blue and green are not two sets of pods but two entire clusters. This is common when upgrading the Kubernetes version itself, changing the network layer, or moving between regions. Traffic is switched outside the cluster using DNS or a global load balancer, and the old cluster is kept until the new one has proved itself.

This pattern gives the strongest isolation and the most dramatic rollback, but it is also the most expensive because you pay for two full clusters. DNS changes can be slow to spread because resolvers cache answers for the time set in the record, so many teams prefer a weighted load balancer for the switch.

PatternWhere the switch livesComplexitySwitch styleBest suited for
1. Service selectorKubernetes ServiceLowAll or nothingLearning and small teams
2. Ingress or GatewayWeb routing layerLow to mediumAll or nothing, header routing, weightsWeb apps needing private test access
3. Service meshMesh routing rulesHighPrecise weights and header rulesLarge microservice estates
4. ControllerRollout or Flagger logicMediumAutomated with analysisTeams releasing often
5. Whole clusterDNS or global load balancerHighCoarse, depends on cachingCluster upgrades and region moves
i
Where to start

Begin with Pattern 1 to understand the mechanics with your own eyes. Move to a controller once you release often enough that manual steps become a source of mistakes. Reach for a mesh or whole-cluster approach only when you already need those tools for other reasons.

6Internal Working: What Happens When You Flip the Switch

The cutover looks instant from the outside, but a small chain of events runs inside the cluster. Knowing that chain explains every strange behaviour you will ever see.

The journey of an ordinary request

First, let us follow a normal request before any switching happens. A user types your web address. DNS, the internet’s phone book, turns the name into the address of a cloud load balancer. The load balancer forwards the request to an ingress controller running inside your cluster. The ingress controller inspects the request and forwards it to a Service. Finally, forwarding rules on the computer receiving the request pass it to one of the ready pods behind that Service.

The important detail is that the Service is not a program that sits in the middle handling every packet. It is a set of forwarding rules programmed into every node of the cluster. A component called kube-proxy watches Kubernetes and keeps those rules current. Depending on configuration, the rules live in the kernel’s packet filtering tables, in a virtual server table, or in the newer nftables system.

The chain of events at cutover

Now let us flip the selector on a Service from blue to green, and follow what happens. The sequence diagram below shows the actors and the order of messages.

sequenceDiagram
    participant O as Operator
    participant A as API Server
    participant E as EndpointSlice Controller
    participant K as kube-proxy on each node
    participant U as Users
    participant B as Blue Pods
    participant G as Green Pods
    O->>A: Change Service selector to green
    A->>E: Service change event
    E->>A: Update EndpointSlices with ready green pods
    A->>K: Watch event with new endpoints
    K->>K: Rewrite forwarding rules
    U->>G: New connections now reach green
    U-->>B: Existing connections finish on blue
        
FIG 2 — The chain of events after the Service selector is changed
1

The change is recorded

The operator or the pipeline sends the new selector to the API server, which stores it in etcd, the cluster’s database. Nothing has moved yet; the desired state has simply been written down.

2

The endpoint controller reacts

A controller notices that the Service now selects a different set of pods. It looks up every pod carrying the green labels and keeps only those whose readiness probe is passing.

3

EndpointSlices are rewritten

The controller updates the EndpointSlice objects so they list the addresses of the ready green pods and no longer list the blue ones.

4

Every node learns the news

kube-proxy on each node is watching the EndpointSlices. When they change, each node rewrites its own local forwarding rules. This happens on many nodes independently, so it is not perfectly simultaneous.

5

New connections go to green

From the moment a node has updated its rules, any new connection it forwards lands on a green pod.

6

Old connections stay put

Connections that were already open keep flowing to the blue pod they started with, because the node remembers each conversation until it ends. This is why blue must stay alive after cutover.

7

The ingress controller adjusts

Many ingress controllers read endpoints directly and update their own routing table when they change, so the same shift also happens in the layer above the Service.

Simple Analogy

Imagine a city that decides to change the direction on every road sign at once. The order is given in one moment, but each sign painter has to walk to his own sign. For a short while, some corners point to the old road and some to the new one. Drivers already on the old road keep driving until they reach the end of it.

Why the switch is not truly instant

Because each node updates on its own schedule, there is a short window, usually a second or a few seconds, when some nodes still send traffic to blue and others already send it to green. During that window, users may be served by either version. This is called eventual consistency, and it is normal in distributed systems.

The practical lesson is that blue and green must be able to live together for a moment. A request that begins on green must not break because the next request lands on blue, and the same data must make sense to both. That requirement, called backward compatibility, is the theme of Chapter 8.

!
Long-lived connections

WebSockets, gRPC streams, database sessions, and HTTP keep-alive connections can last minutes or hours. After cutover, users on such connections stay on blue until they reconnect. If blue is deleted too early, those users are cut off abruptly, so always plan a drain period.

Graceful shutdown when blue finally goes away

When blue pods are eventually removed, Kubernetes sends each one a polite termination signal, and the pod is expected to finish the work it is doing. A setting called the termination grace period gives the pod a fixed number of seconds to finish before Kubernetes forcefully stops it. An optional pre-stop hook can add a short delay so that the forwarding rules have time to stop sending new requests to the pod.

Applications that ignore the signal, or that take longer to finish than the grace period, drop requests during cleanup. A well-behaved application stops accepting new work, completes what is in flight, closes its connections, and then exits.

7The Full Lifecycle, Step by Step

A blue-green release is a loop with clear stages, decision points, and an escape hatch at every step.

Every release follows the same lifecycle, and the discipline of following it each time is what makes the process safe. The flowchart below shows the stages and the two decision points where the release either continues or turns back.

flowchart TD
    A["Blue is live"] --> B["Deploy new version to green"]
    B --> C["Wait for green pods to be ready"]
    C --> D["Run smoke tests on the preview address"]
    D --> E{"Tests pass?"}
    E -->|"No"| F["Fix and redeploy green"]
    F --> C
    E -->|"Yes"| G["Switch traffic to green"]
    G --> H["Watch metrics during soak period"]
    H --> I{"Healthy?"}
    I -->|"No"| J["Switch back to blue"]
    I -->|"Yes"| K["Scale down blue, keep it ready for next release"]
        
FIG 3 — The release loop with its two decision points
1

Prepare capacity

Confirm the cluster has enough room to run a full second copy. Check CPU, memory, quotas, and node limits before you start, because a half-scheduled green environment is a common cause of failed releases.

2

Deploy to the idle colour

Roll the new image into the idle Deployment. Because no user is connected to it, this can be slow and careful without any pressure.

3

Wait for readiness

Do not proceed until every green pod reports ready. A pod that is running but not ready is a warning, not a success.

4

Test privately

Use the preview address to run smoke tests, integration checks, and load tests against green. Chapter 9 covers this in detail.

5

Warm up

Send some synthetic traffic so caches fill, connection pools open, and the runtime reaches normal speed. A cold environment can look slow to the first real users.

6

Cut over

Flip the switch. Record the exact time, because it will help you match any change in the graphs to the release.

7

Soak and observe

Watch error rate, latency, and business numbers closely. Keep blue running and untouched. The length of the soak depends on how quickly problems tend to show up in your system.

8

Retire or keep standby

Once you are confident, scale blue down to save cost, but keep its definition so it can be revived quickly. Blue becomes the idle target for the next release.

i
Automate the boring parts

Every step above should be a pipeline stage, not a checklist that a tired human follows at night. Automation removes the small slips, such as forgetting to check readiness, that cause the biggest outages.

8The Hard Part: Databases and Other State

Stateless pods are easy to duplicate. Anything that remembers things, such as databases, caches, and queues, is where blue-green gets difficult.

Duplicating pods is cheap because pods forget everything when they stop. But your application also depends on things that remember. A database holds customer records. A cache holds frequently used answers. A queue holds work waiting to be done. You almost never duplicate these, so blue and green usually share them, and that sharing is where most blue-green problems are born.

Simple Analogy

Imagine our two theatres sharing one warehouse of props. If the crew for the new play rearranges the shelves in a way the old crew does not understand, the old stage can no longer find its props. Both stages must be able to use the warehouse at the same time, even while it is being reorganised.

The database schema problem

A schema is the shape of a database, meaning its tables and columns. Suppose the new version needs a column renamed. If you rename it and cut over, green works fine, but blue, which is still your rollback target, now fails because it looks for the old name. Your safety net has quietly disappeared.

The cure is a discipline called expand and contract, also known as parallel change. You never make a breaking database change in the same release as the code that needs it. Instead, you spread the change across several releases so that every version of the code can work with every version of the schema that might exist at the same time.

flowchart LR
    A["Step 1: Expand the schema, old and new both work"] --> B["Step 2: Deploy green, compatible with both shapes"]
    B --> C["Step 3: Switch traffic to green"]
    C --> D["Step 4: Soak, blue kept as safety net"]
    D --> E["Step 5: Contract, remove old parts in a later release"]
        
FIG 4 — Expand and contract: breaking changes are split across releases
1

Expand

Add the new column or table without removing anything. Both old and new code continue to work because nothing they rely on has changed.

2

Migrate

Deploy the new version to green so it writes to both the old and the new structure, or reads from whichever one has data. Copy existing data across in the background if needed.

3

Switch and soak

Cut over, and keep blue available. Because the old structure is still there and still updated, a rollback is safe.

4

Contract

Only in a later release, after you are certain you will never roll back to the old code, remove the old column or table.

!
Irreversible changes

Dropping a column, deleting data, or changing a data type in place cannot be undone by flipping a switch. If a release includes such a change, blue-green no longer protects you, and you need a backup and a separate recovery plan.

Other kinds of state and how they behave

User sessions

If login sessions live inside the memory of a pod, every user is logged out at cutover. Store sessions in a shared store such as Redis, or use signed tokens that any pod can verify, so the switch is invisible to users.

Caches

A shared cache may contain data shaped by the old code. If green reads it and misunderstands it, you get strange bugs. Put a version number in cache keys so each version uses its own entries, or make sure the stored format stays compatible.

Message queues and background workers

If both blue and green workers consume from the same queue, both will process messages, and a message may be handled by the wrong version. Either keep message formats compatible, or keep green workers scaled to zero until cutover and then move them over together.

Scheduled jobs

A job meant to run once per night must not run in both environments. Let only the live colour own scheduled jobs, and move that ownership as part of the cutover.

Files and object storage

Uploaded files usually live in shared storage. Make sure the new version can read files written by the old one and that the old one can still read files written by the new one until the soak is over.

9Testing Green Before Users See It

The biggest gift of blue-green is a safe place to prove the new version works. It is only a gift if you actually use it.

Because green is fully running yet invisible to users, you can test it in conditions that are very close to production. This is far more realistic than a smaller staging environment, since green runs on the same cluster, with the same network rules, the same configuration style, and often the same real dependencies. Many bugs that only appear in production show up here first.

Simple Analogy

Green is a full dress rehearsal on the real stage, with the real lights and the real props, before opening night. The audience is not there yet, so a forgotten line costs nothing. A rehearsal in a different, smaller room would never reveal that the real stage has a squeaky trapdoor.

How testers reach green

Testers need an address that leads to the idle colour and nowhere else. Common choices are a preview Service that always selects the idle pods, a separate internal hostname handled by the ingress, or a special request header that the router recognises. Whichever you pick, it must be reachable by your tests but not by the public.

What to test

Test 1

Smoke Tests

Fast checks of the most important paths, such as loading the home page, logging in, and completing a purchase.

Test 2

Integration Tests

Checks that green can talk to its real neighbours, such as the database, payment provider, and other services.

Test 3

Load Tests

Push realistic traffic volumes at green to make sure it can carry the same load as blue before it is asked to.

Test 4

Compatibility Tests

Confirm that green works with data written by blue and that blue can still read data written by green.

Test 5

Synthetic Transactions

Scripted fake users performing full journeys, marked clearly so they do not pollute real business reports.

Test 6

Traffic Mirroring

Copy a share of real requests to green and discard its answers, comparing behaviour with blue without affecting anyone.

Warm-up matters

A freshly started application is often slower than one that has been running for an hour. Caches are empty, programs written in languages that compile as they run have not yet optimised their hot paths, and database connection pools are still small. If you cut over a cold green environment, the first real users pay the price with slow responses. A short warm-up with synthetic traffic avoids this.

i
Decide the pass rules in advance

Write down what “good enough to switch” means before the release begins, such as zero failed smoke tests and error rate below a fixed number under load. Deciding in advance stops the team from talking itself into a risky cutover at the end of a long day.

!
Beware of side effects

Tests against green use the real database and real integrations. A test that places an order might charge a real card or send a real email. Use test accounts, sandbox modes for external providers, and clear markers so test activity can be told apart from real activity.

10Advantages, Disadvantages, and Trade-offs

Blue-green is powerful, but nothing in engineering is free. Here is an honest look at what you gain and what you pay.

Advantages

  • Users normally see no downtime during the switch.
  • Rollback is quick because the old version is still running and warm.
  • The new version can be tested privately in production-like conditions.
  • Only one version serves users at any time, apart from a brief overlap, which makes behaviour easy to reason about.
  • Deployment and release are separated, so risky work happens away from users.
  • The process is repeatable and easy to explain to non-engineers.

Disadvantages / Trade-offs

  • You need capacity for two full environments, at least for a while.
  • Shared databases and other state make rollback harder than it looks.
  • The switch is all or nothing, so every user is exposed to the new version at the same moment.
  • Kubernetes does not provide it natively, so you must build or install the machinery.
  • Long-lived connections and background jobs need special care.
  • Two environments can slowly drift apart if they are not created from the same template.

Thinking about cost honestly

The cost of blue-green is mostly the cost of the second environment. If your application uses ten large pods, you need room for twenty during the release. That extra room may already be free in your cluster, or your cluster autoscaler may need to add computers for a while, which takes time and money. The good news is that the cost lasts only for the hours or days of the soak period, and you can scale the idle side to zero afterwards.

Compare that to the cost of an outage or a bad release. For a business where an hour of downtime costs more than a month of extra computers, blue-green is very cheap insurance. For a small internal tool used by ten people, it is probably more machinery than it deserves.

How it compares with the other strategies

QuestionBlue-GreenCanaryRolling Update
How many users see a bad release before you notice?All of them, until you roll backOnly the small canary sliceA growing share as the rollout progresses
Extra costHigh, a full second copyLow to mediumLow
Rollback speedVery fastFast, set the slice to zeroSlow
Setup effort in KubernetesMediumMedium to high, needs weighted routingNone
Best whenYou want a clean switch and instant undoYou want to limit the blast radius using real usersChanges are small and low risk
i
You can combine strategies

Many mature teams use blue-green for the environment and canary-style weights for the traffic. They keep the two full environments for safety, but move users across in steps such as five, twenty-five, and one hundred percent, watching the graphs between steps.

11Security in a Blue-Green World

Two environments and a powerful switch create new things to protect. Security has to be designed in, not added afterwards.

A blue-green setup has two special features from a security point of view. First, there are twice as many running workloads, so any weakness is doubled. Second, the switch is a very powerful control, because whoever can change it can decide what code real users run. Both deserve deliberate protection.

Control 1

Restrict Who Can Switch

Use Kubernetes role-based access control so that only the pipeline or a small approved group can change the Service, route, or Rollout that decides live traffic.

Control 2

Trust Only Known Images

Build images in a controlled pipeline, scan them for known vulnerabilities, sign them, and let the cluster admit only signed images.

Control 3

Identical Policies

Apply the same network rules, pod security settings, and resource limits to both colours so the idle side is never a weaker copy.

Control 4

Protect the Preview Address

The preview endpoint exposes unreleased features. Keep it on an internal network or behind authentication.

Control 5

Secrets Parity and Rotation

Both colours need their secrets. Store them in a proper secrets system, give each colour only what it needs, and rotate them on a schedule.

Control 6

Network Policies

Limit which pods may talk to which, so a compromised idle environment cannot freely reach the live one or the database.

Control 7

Admission Control

Use admission policies that reject pods breaking your rules, such as running as an administrator or using an unpinned image tag.

Control 8

Audit Trail

Record who changed the switch, when, and why. During an incident, this record is often the first thing investigators need.

A secure delivery path

The safest way to reach the switch is through a controlled path where every step is checked and recorded. A popular approach is called GitOps, where the desired state of the cluster is stored in a Git repository and a controller inside the cluster continuously makes reality match it. People request a cutover by changing a file and getting it approved, rather than by typing commands into a production cluster.

flowchart LR
    A["Developer"] --> B["Git repository"]
    B --> C["CI build and scan"]
    C --> D["Signed image in registry"]
    D --> E["GitOps controller"]
    E --> F["Idle colour in cluster"]
    F --> G["Approved switch"]
        
FIG 5 — A controlled delivery path from code change to approved cutover

Each stage in the figure is a checkpoint. The build stage scans and signs the image. The registry stores only what passed. The controller deploys only what Git says. The final switch needs an approval, human or automatic, that is written to an audit record. If any step fails, the chain stops before real users are affected.

Simple Analogy

Think of a bank vault that needs two keys held by two different people. One person alone cannot open it, and every opening is written in a logbook. The switch that decides what code real users run deserves the same care, because it can just as easily deliver a harmful change as a helpful one.

!
The forgotten idle environment

Teams often patch and monitor the live colour carefully and forget the idle one. An idle environment running an old, vulnerable image is still inside your network and can still be attacked. Treat both colours as production-grade at all times, and scale the idle one down when it is not needed.

12Monitoring, Logging, and Metrics

A blue-green release is only as safe as your ability to see what is happening. The switch is quick, but noticing a problem is up to your dashboards.

Simple Analogy

A pilot does not fly by feel. The cockpit shows altitude, speed, fuel, and engine health at a glance, so a small drift is noticed long before it becomes a crash. Monitoring gives your release the same instruments. Without them you are flying through cloud and hoping the ground is far away.

The four golden signals

Site reliability engineers often summarise service health with four signals. You should be able to see all four for blue and green separately, and side by side.

Signal 1

Latency

How long requests take. Track the slow tail, such as the ninety-ninth percentile, not only the average, because the slowest users feel problems first.

Signal 2

Traffic

How many requests arrive. A sudden drop after cutover can mean users are failing before they even reach your application.

Signal 3

Errors

How many requests fail, including hidden failures such as a success code carrying a wrong answer.

Signal 4

Saturation

How full your resources are, such as CPU, memory, connections, and disk. A full system is a system about to fail.

Label everything with colour and version

The most useful habit in blue-green monitoring is to attach the colour and the version to every metric, log line, and trace. When the dashboards show a spike, you can immediately ask whether it belongs to blue or green. Without that label, you can only see one blended picture, and you lose the ability to compare the old version with the new one at the same moment.

What to watch, phase by phase

1

Before cutover

Watch green’s startup: readiness time, restarts, memory at rest, and connection errors to dependencies. A green pod that restarts repeatedly is not ready for users.

2

The first minutes after cutover

Watch error rate, latency, and traffic volume in real time. Most obvious problems appear here, so keep a person or a well-tuned automatic check watching closely.

3

The soak period

Watch slower problems: memory that creeps upward, queues that slowly grow, and business numbers such as orders per minute compared with the same time last week.

4

After retiring blue

Confirm nothing was still quietly using blue, such as an old client on a long connection or an internal tool pointing at the wrong address.

Logs and traces

Write logs in a structured form, such as one record per line with named fields, and include the colour, version, and a request identifier in every record. A request identifier lets you follow one user action across many services. Distributed tracing, supported by open standards such as OpenTelemetry, draws the whole path of a request and shows exactly which step became slow after the release.

Also remember that logs from blue disappear from the cluster when blue pods are deleted, unless they were shipped elsewhere. Send logs to a central store as they are written, and keep them long enough to investigate problems that surface days after the release.

Business metrics are the ultimate health check

Technical graphs can look perfect while the business quietly suffers. A checkout button that silently fails still returns a healthy response. Track outcomes that matter, such as sign-ups, completed payments, and search results clicked, and compare them before and after the switch.

i
Automatic rollback triggers

Decide in advance the numbers that force a rollback, such as error rate above a set value for a set number of minutes. A controller can then flip the switch back without waiting for a human to wake up, read a chart, and decide.

!
Beware of thin data

At quiet times, a few requests can make a percentage jump wildly. One failure out of five requests looks like twenty percent errors. Choose release windows with enough traffic to make the numbers meaningful, and set alert rules that require a minimum number of requests.

13Design Patterns and Anti-patterns

Some habits make blue-green smooth and boring. Others turn it into a source of midnight incidents.

Patterns that work well

Pattern 1

Expand and Contract

Split breaking data changes across releases so every version of the code works with every version of the schema.

Pattern 2

Immutable Infrastructure

Never edit a running pod. Build a new image, deploy it fresh, and replace the old. What you tested is exactly what runs.

Pattern 3

GitOps

Keep the desired state in Git and let a controller apply it, so every change is reviewed, versioned, and reversible.

Pattern 4

Feature Flags Alongside Blue-Green

Ship new features switched off, cut over the code, and then enable features gradually. Code release and feature release become two separate decisions.

Pattern 5

Tolerant Readers and Versioned APIs

Design clients and services so they ignore fields they do not understand and keep old fields working, allowing blue and green to talk to each other safely.

Pattern 6

Blue-Green with Stepped Weights

Keep two full environments but move users in stages, gaining the safety of blue-green and the small blast radius of a canary.

Anti-patterns to avoid

ANTI-PATTERN-01 Avoid
Problem

The release includes a database change that removes or renames something the old version still needs, and the team cuts over immediately.

Why It’s Harmful

The rollback target stops working the moment the schema changes. The team believes it has a safety net, but the net has a hole, and this is discovered exactly when it is needed.

Correct Approach

Use expand and contract. Add first, switch traffic, and remove old structures only in a later release after the soak has finished and rollback is no longer needed.

ANTI-PATTERN-02 Avoid
Problem

Blue and green are treated as two separately maintained systems, edited by hand, with configuration copied and tweaked over time.

Why It’s Harmful

The two environments drift apart. Green then passes its tests under settings that differ from blue’s, and what was tested is no longer what will run for users.

Correct Approach

Generate both colours from one template with only the version and colour changing, and keep that template in version control.

ANTI-PATTERN-03 Avoid
Problem

Images are referenced by a moving tag such as “latest”, or pods are edited in place after they start.

Why It’s Harmful

Nobody can say exactly which code is running in blue or green, and a restarted pod may silently pull a different image than its neighbours.

Correct Approach

Pin images to a specific version or a content digest, and replace pods instead of modifying them.

ANTI-PATTERN-04 Avoid
Problem

The old environment is deleted the moment the switch is flipped, to save cost or tidy up.

Why It’s Harmful

The biggest benefit of blue-green, instant rollback, is thrown away. Users on long connections are also cut off, and a slow-burning bug has nowhere to roll back to.

Correct Approach

Keep the old environment running through a defined soak period. Afterwards, scale it down but keep its definition ready.

14Best Practices and Common Mistakes

A short field guide collected from the way experienced teams run blue-green, and from the ways beginners get hurt.

Best practices

  • Make readiness probes honest — they should check that the application can really serve requests, including its critical dependencies.
  • Generate both colours from one template — only the colour label and version should differ.
  • Pin every image — use exact versions or digests so what you tested is what runs.
  • Size green like blue before cutover — if blue is running twenty pods under load, green must be ready to carry the same load the instant it receives traffic.
  • Set resource requests and limits — this lets the scheduler place both environments properly and protects neighbours from noisy pods.
  • Use disruption budgets — a PodDisruptionBudget stops cluster maintenance from removing too many pods at once during a soak.
  • Plan for graceful shutdown — configure grace periods and pre-stop pauses so retiring blue does not drop in-flight requests.
  • Keep data changes backward compatible — follow expand and contract in every release that touches the schema.
  • Define the soak period and rollback rules in advance — remove guesswork from stressful moments.
  • Practise rollback — run drills on a normal day so the first rollback is not also the first time anyone has tried it.
  • Reserve cluster capacity — confirm quotas and autoscaler limits allow a full second copy before the release starts.
  • Record every cutover — note the time, the version, and who approved it, so graphs and incidents can be matched to changes.

Common mistakes

!
Mistake 1: Cutting over a green that is too small

Green often starts with a minimum number of pods and relies on autoscaling to catch up. At cutover it suddenly receives all the traffic and is overwhelmed before the autoscaler reacts. Scale green to match blue’s current size first.

!
Mistake 2: Forgetting the workers and scheduled jobs

Teams carefully switch the web tier and forget that background workers and nightly jobs run in both colours. The result is duplicate emails, double-processed payments, or reports generated twice. Decide which colour owns each background task.

!
Mistake 3: Trusting DNS for a fast switch

When the switch is a DNS change, many users and resolvers keep the old answer until it expires, and some ignore expiry times. The cutover becomes slow, uneven, and hard to reverse. Use a load balancer or in-cluster routing for fast, controllable switching.

i
Keep it boring

The best blue-green process is one nobody talks about, because it happens the same way every time, on any weekday, at any hour. If cutovers feel dramatic, that is a sign that something in the process still depends on heroics.

15Real-World and Industry Examples

The pattern is older than Kubernetes, and it shows up wherever downtime is expensive and rollback speed matters.

Platform-as-a-service routing

Before Kubernetes was common, platforms such as Cloud Foundry documented blue-green as a routine technique. Operators started the new version as a separate application, mapped the public route to it, and unmapped the route from the old one. The idea of moving a stable address between two running copies is exactly what a Kubernetes Service does today.

Large streaming and delivery platforms

Netflix has described a red and black approach in its Spinnaker tool, where a new group of servers is brought up beside the old one, traffic is moved over, and the old group is disabled but kept briefly in case it is needed. Spinnaker became an open source project and supports similar strategies for Kubernetes targets.

Retail during peak seasons

Online shops that cannot afford a broken checkout during sales events often prefer blue-green, because they can rehearse the new version under realistic load in advance and undo it in seconds if orders start failing. Many pair it with a code freeze and pre-scaled capacity.

Financial services and regulated industries

Where change approvals and audit trails are strict, blue-green fits naturally. The release is a documented, approved switch with a recorded time, and the rollback plan is a single, tested action rather than a hurried redeployment.

Software-as-a-service products

Companies serving many customers use blue-green so that no customer sees a maintenance page. Some combine it with weighted routing to move internal users first, then a small share of customers, and finally everyone.

Kubernetes and platform upgrades

Platform teams build a whole new cluster on the newer Kubernetes version, move workloads and traffic across gradually, and keep the old cluster available until the new one has proved stable. This is whole-cluster blue-green, and it avoids risky in-place upgrades of a running production cluster.

Teams using progressive delivery tools

Organisations that release many times a day frequently adopt Argo Rollouts or Flagger so that each release follows the same automatic steps: deploy, preview, analyse, promote, and clean up. The consistency reduces mistakes more than any single clever feature.

16Frequently Asked Questions

Quick answers to the questions that come up most often when teams adopt blue-green in Kubernetes.

Q1Do I need two clusters for blue-green?

No. In most cases blue and green are two Deployments inside one cluster, often in the same namespace. Two clusters are only needed for whole-cluster blue-green, such as during a Kubernetes version upgrade or a region move.

Q2Is blue-green better than canary?

Neither is better in every case. Blue-green gives a clean switch, private testing, and instant rollback, but exposes everyone to the new version at once. Canary limits how many users see a problem, but needs weighted routing and takes longer. Many teams combine them.

Q3How long should I keep the old environment?

Long enough that a problem would very likely have shown itself. For a busy service that may be a few hours; for one with weekly or monthly cycles, such as billing runs, it may be days. Choose the period based on how your own problems tend to appear.

Q4Won’t running two copies double my bill?

Only for the duration of the release and soak. Afterwards you can scale the idle side to zero and keep its definition ready. Compare that short cost with the cost of downtime or a slow, risky rollback.

Q5Can I do blue-green for a database running inside Kubernetes?

It is far harder. Databases hold the truth, so two live copies would disagree. Teams usually apply blue-green to the stateless application tier and manage databases with careful backward-compatible changes, replication, and separate migration procedures.

Q6What happens to autoscaling?

Each Deployment has its own autoscaler. Before cutover, make sure green is scaled to at least the size blue currently needs. Otherwise green may be overloaded in the seconds before its autoscaler reacts.

Q7Will users notice the switch?

Usually not, provided sessions are stored outside the pods, the versions are compatible for the short overlap, and long-lived connections are drained gracefully. Users on WebSockets or streams may reconnect once.

Q8Can I use Helm for blue-green?

Yes. A common approach is to install the same chart twice with different colour values, and let the pipeline change which one the live Service or route points to. The important point is that both installs come from the same chart so they cannot drift.

Q9What if green wrote new data before I rolled back?

If blue can still read and safely use that data, the rollback is fine. This is why data must stay backward compatible during the soak. If green wrote data in a shape blue cannot understand, a rollback may cause errors and needs a recovery plan.

Q10Why not just use a rolling update and the rollback command?

A rolling rollback has to start and warm up old pods again, which takes as long as the original rollout, while both versions serve users. A blue-green rollback moves traffic to pods that are already running and warm, so it is much faster and more predictable.

Q11Should every service use blue-green?

No. It fits critical, user-facing services where downtime or a slow rollback is costly. A small internal tool or a low-risk change is often better served by an ordinary rolling update, which is simpler and cheaper.

Q12Can the switch be automated safely?

Yes, and it usually should be. Progressive delivery controllers can run tests, check metrics, promote automatically, and roll back on failure. Keep an approval gate for high-risk releases and make sure every automatic action is logged.

17Summary and Key Takeaways

Blue-green deployment is a simple idea with deep consequences. You keep two identical environments, prepare and test the new version on the idle one, and then move users across with one switch. Because the old version is still running, undoing a mistake is as quick as flipping the switch back. Kubernetes does not provide this as a single button, but its Services, labels, readiness probes, and routing layers give you every piece you need, and controllers such as Argo Rollouts can automate the choreography.

The technique is not magic. It costs extra capacity, it makes shared state the central challenge, and it demands honest health checks, good monitoring, and disciplined data changes. Teams that respect those requirements turn releases from stressful events into ordinary, repeatable routines.

Key Takeaways

  • Two environments, one switch — keep blue and green identical, send users to one, and test the other privately before cutover.
  • Labels and selectors make it possible — a Service, Ingress, mesh rule, or controller decides which pods receive traffic, and changing that target is the cutover.
  • The switch is fast, not instant — nodes update on their own schedule, and long-lived connections stay on the old version, so keep blue alive and drain gracefully.
  • State is the real challenge — use expand and contract for databases, and treat sessions, caches, queues, and scheduled jobs deliberately.
  • Test green like it is production — use a private preview address, smoke and load tests, and a warm-up before any user arrives.
  • Watch, secure, and automate — label metrics by colour, define rollback triggers, restrict who can flip the switch, and let pipelines perform the steps.
  • Match the strategy to the risk — use blue-green where instant rollback is worth a second copy, and combine it with canary weights when you also want a small blast radius.