Software Engineering·July 21, 2026·4 min read

Deployment Strategies

A deployment strategy controls how a new version of your app reaches users — all at once, gradually, or behind a feature flag. This guide explains the main approaches and when to use each.

deploymentdevopscicdreleaseengineering

A deployment strategy controls how a new version of your app reaches users. The simplest approach — replace the old version with the new one all at once — works, but if the new version is broken, every user hits the problem immediately. Better strategies limit the blast radius and make rollback fast.

If Cartara flagged this in your diff, you likely changed a deployment config, added feature flags, or modified how your app handles rollouts.


Why Strategy Matters

Every deployment carries risk. A good strategy does two things:

  1. Limits blast radius — how many users are affected if a release is bad
  2. Makes rollback fast — how quickly you can get back to a working state

The trade-off is usually cost and complexity. Safer strategies require more infrastructure or better monitoring.


The Main Strategies

Recreate (Big Bang)

Stop the old version, start the new one all at once. Simple, but causes a brief period of downtime and exposes every user to problems simultaneously.

Use when: Internal tools, staging environments, or apps where a short outage is acceptable.

Rolling

Replace running instances with the new version gradually — a few at a time — until all are updated. No downtime, and it's the default on most platforms including Kubernetes.

Catch: Old and new versions run side by side during the rollout. Your changes (especially database changes) must be backward-compatible. See Database Migrations.

Use when: Most standard deployments on platforms that support it.

Blue-Green

Run two identical environments. "Blue" serves live traffic while "green" gets the new version. Once verified, you flip all traffic to green. Rollback is instant — just switch back to blue.

Catch: Requires running two full environments at once, which doubles infrastructure cost.

Use when: High-stakes releases where instant rollback is worth the cost.

Canary

Release the new version to a small slice of users first (e.g. 5%), watch error rates and metrics, then gradually increase if everything looks healthy. Catches problems with real traffic before they reach everyone.

Catch: Requires solid monitoring to be worthwhile — otherwise you're just exposing 5% of users to bugs with no signal.

Use when: You have good observability and want data-driven rollouts.

Feature Flags

Deploy code with a new feature switched off, then turn it on for selected users at runtime — no redeploy needed. This decouples deploying code from releasing a feature, and gives you an instant kill switch. It's also the foundation of A/B testing.

Tools: LaunchDarkly, Flagsmith, Statsig, or a simple config table in your database.

Use when: You want to ship code before a feature is ready to reveal, or test a change on a subset of users.


Quick Comparison

StrategyDowntimeRollback SpeedCostBest For
RecreateYesSlow (redeploy)LowInternal tools, staging
RollingNoMediumLowMost standard deployments
Blue-GreenNoInstantHigh (2× infra)High-stakes releases
CanaryNoFastMediumGradual, data-driven rollout
Feature FlagsNoInstant (toggle)Low–MediumDecoupling release from deploy

These aren't mutually exclusive — feature flags are often layered on top of rolling or canary deploys for the finest control.


What You'll See in Your Code

Feature flags appear as conditional checks in your code:

// Check a flag before showing a new feature
if (featureFlags.isEnabled('new-checkout-flow', user.id)) {
  return <NewCheckoutFlow />;
} else {
  return <OldCheckoutFlow />;
}

Deployment configs (Kubernetes, Docker Compose, or platform-specific files) often specify the rollout strategy:

# Kubernetes deployment with rolling update strategy
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

Database Changes and Zero-Downtime Deploys

The hardest part of any zero-downtime strategy is the database. During a rolling or canary deploy, old and new versions of your app run simultaneously against the same database — so schema changes must be backward-compatible.

Use the expand-and-contract pattern:

  1. Expand — add new structure without removing old (e.g., add a new column, don't rename yet)
  2. Migrate — deploy code that writes to both old and new structures
  3. Contract — remove the old structure in a later, separate release

A migration that drops a column the old code still reads is the most common cause of a "zero-downtime" deploy causing downtime.


What Most Teams Need

If you're on Vercel, Netlify, Railway, or Render, you already get rolling deploys and instant rollback out of the box. Start there.

Add feature flags when you want to ship code before it's ready to reveal, or test with a subset of users. Consider canary or blue-green only when an outage genuinely costs you money or trust.

The real prerequisite for any strategy is monitoring — you need to be able to see that a release is bad before you can act on it.


Related concepts

CI/CD Basics
CI/CD automates the process of testing and shipping code. This guide explains continuous integration, continuous deployment, how pipelines work, and how to set one up.
GitOps and Kubernetes
What Kubernetes does, what GitOps adds on top of it, and when this combination is worth adopting — explained for builders who haven't managed clusters before.
CI/CD Security and Supply Chain
How to protect your deployment pipeline and the software it produces — keeping secrets safe, scanning dependencies, and understanding where attacks actually happen.

Turn shipping into understanding

Cartara measures what your team actually learns from every AI coding session.

Join the waitlist