Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Feature Flag

Pattern

A reusable solution you can apply to your work.

Also known as: Feature Toggle, Feature Switch, Feature Gate

Understand This First

  • Configuration – flag state is a form of runtime configuration.

Context

This is an operational pattern that decouples two things that most teams assume must happen together: deploying code and exposing it to users. A feature flag is a conditional check in your code that determines whether a feature is active. The flag’s state is controlled through Configuration, not through code changes, which means you can turn features on or off without deploying.

In agentic coding, feature flags are especially valuable. Agents can generate features quickly, and flags let you deploy that code to production immediately for testing without exposing it to users until you are confident it works.

Problem

You have a half-finished feature on a branch. It isn’t ready for users, but you want to merge it to avoid a long-lived branch that diverges from main. Or you have a finished feature that you want to test in production before all users see it. Or you want to release to 5% of users first and gradually roll out. In all these cases, you need to separate “the code is deployed” from “the user sees it.” How?

Forces

  • Long-lived feature branches diverge from main and create painful merges.
  • Deploying unfinished or unvalidated features directly to users is risky.
  • Rolling out a feature to everyone at once means any problem affects all users simultaneously.
  • Adding conditional logic for flags increases code complexity.

Solution

Wrap new or experimental features in conditional checks that read from a configuration source:

if feature_flags.is_enabled("new_search_algorithm", user=current_user):
    results = new_search(query)
else:
    results = old_search(query)

The flag’s state can be controlled through a configuration file, a database, an admin dashboard, or a feature flag service (LaunchDarkly, Unleash, Flipt, or similar). This means you can:

  • Deploy dark: Ship code to production with the flag off. The code is live but invisible.
  • Test in production: Enable the flag for internal users or a test group.
  • Gradual rollout: Enable the flag for 1%, then 10%, then 50%, then 100% of users.
  • Instant rollback: If problems appear, disable the flag. No redeployment needed.

Feature flags come in several varieties: release flags (temporary, controlling a new feature rollout), experiment flags (A/B tests comparing variants), ops flags (circuit breakers for degraded services), and permission flags (enabling features for specific user tiers). Release flags should be removed after the feature is fully rolled out. Ops and permission flags may be permanent.

When working with an AI agent, you can ask it to implement features behind flags from the start: “Add the new recommendation engine behind a feature flag called new_recommendations. Default to off.”

How It Plays Out

A team deploys a new checkout flow behind a feature flag. They enable it for 5% of users and monitor conversion rates and error rates for a week. The new flow has a 3% higher conversion rate and no increase in errors. They gradually increase the rollout to 100% over three days. If problems had appeared at any point, disabling the flag would have instantly reverted all users to the old flow. No deployment required.

An agent generates a new API endpoint. The developer deploys it behind a flag, tests it with curl against production, finds and fixes a serialization bug, and then enables it for the mobile client. The flag gave them a safe way to iterate on production without affecting users.

Warning

Feature flags that are never cleaned up become technical debt. They add conditional complexity to the codebase and make it harder to reason about behavior. Establish a practice of removing flags once a feature is fully rolled out and stable.

Example Prompt

“Deploy the new checkout flow behind a feature flag called new_checkout. Default it to off. I want to enable it for 5% of users first and monitor error rates before a full rollout.”

Consequences

Feature flags give you fine-grained control over what users experience, independent of what code is deployed. This enables safer deployments, faster experimentation, and the ability to respond to problems in seconds rather than minutes. Combined with Continuous Delivery, flags make it practical to deploy to production continuously while maintaining full control over the user experience.

The cost is code complexity. Every flag is a branch in your code, and multiple flags create a combinatorial explosion of possible states. Stale flags (ones never cleaned up after their feature launched) accumulate and make the code harder to understand. Use a feature flag inventory, set expiration dates, and regularly clean up flags that have served their purpose.

  • Depends on: Configuration — flag state is a form of runtime configuration.
  • Supports: Deployment — flags make deployment safer by decoupling it from exposure.
  • Supports: Continuous Delivery — flags enable merging and deploying incomplete features.
  • Supports: Continuous Deployment — flags provide a non-deployment control mechanism.
  • Complements: Rollback — disabling a flag can be faster than a full rollback.