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:
- Limits blast radius — how many users are affected if a release is bad
- 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
| Strategy | Downtime | Rollback Speed | Cost | Best For |
|---|---|---|---|---|
| Recreate | Yes | Slow (redeploy) | Low | Internal tools, staging |
| Rolling | No | Medium | Low | Most standard deployments |
| Blue-Green | No | Instant | High (2× infra) | High-stakes releases |
| Canary | No | Fast | Medium | Gradual, data-driven rollout |
| Feature Flags | No | Instant (toggle) | Low–Medium | Decoupling 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: 0Database 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:
- Expand — add new structure without removing old (e.g., add a new column, don't rename yet)
- Migrate — deploy code that writes to both old and new structures
- 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.