Abhinav C

Deploying is engineering. Releasing is a business decision.

In many organizations, “the release” is a single event. Code is merged, built, deployed, and at that moment customers see the new feature. If something goes wrong, the fix is another deploy, or a rollback that also removes three other teams’ fixes.

That bundles two different decisions:

  • Deploy: is this code safe to run in production? An engineering question, best answered small and often.
  • Release: should customers see this now? A product and business question, often tied to a date, a market or a partner.

Separate them, and both get easier.

Ship dark, turn on deliberately

The mechanism is a feature flag: new code paths are deployed switched off, then turned on independently of any deploy.

  • Deploys become routine. Code goes out continuously, in small pieces, with nothing user-visible changing. Small deploys are easy to review and easy to roll back.
  • Releases become instant and reversible. Turning a feature on is a configuration change that takes effect in seconds. Turning it off is the same. No pipeline, no build, no waiting.
  • Exposure can be gradual. Internal users first, then 1% of customers, then 10%, then everyone, watching error rates and business metrics at each step.

On AWS, AppConfig provides feature flags with validation and gradual rollout, and can roll a change back automatically when a CloudWatch alarm fires. Dedicated flag services and open-source tools work the same way.

Progressive delivery for the deploy itself

The deploy side gets the same treatment at the infrastructure level: blue/green or canary deployments that shift a fraction of traffic to the new version and roll back automatically on alarms. CodeDeploy, ECS and most Kubernetes rollout tools support this. The rule: no deploy should need a human to notice it failed.

Why it matters more in 2026

More code is being written faster, much of it with AI assistance, and the time between writing code and production is shrinking. That’s fine when deploying is cheap and safe and releasing is a deliberate choice. It’s dangerous when every merge exposes customers to new behavior. Separating the two lets the volume of code grow without the number of customer-facing surprises growing with it.

Flags are debt with an interest rate

Feature flags aren’t free. Every flag doubles the paths through a piece of code, and old flags that nobody removes become hidden configuration that nobody dares to touch. Keep them healthy:

  • Give every release flag an owner and an expiry date when it’s created.
  • Remove the flag and the old code path once the feature is fully released. Treat that as part of the feature’s definition of done.
  • Separate release flags (temporary) from operational switches (permanent kill switches for expensive or risky features), and name them differently.

Release engineering used to mean carefully coordinating one big moment. Done well now, there’s no big moment at all: code flows out continuously, and features arrive whenever the business is ready for them.

Filed under: two buttons that used to be one.

More writing