What are feature flags?

A feature flag adds a decision point around behavior that can change without a new deployment of that code. A SaaS might deploy a new export workflow while keeping the existing workflow as the default, then enable the new path for an internal account and a small pilot.

LaunchDarkly's introduction describes flags as a way to separate deploying code from releasing a feature. That separation can make exposure more deliberate, but it also creates two behaviors to maintain and test. The flag service, application code, account identity, and fallback policy all affect what a person receives.

This guide uses an original fictional filtered-export release. The downloads include a decision record and a local teaching example. They demonstrate release logic without connecting to a flag vendor or handling customer data. They are not a production flag platform.

Keep release exposure separate from permission checks

Authorization decides whether an account and person may perform an action on a resource. A release flag decides which eligible experience they receive. Check the required permissions on the server regardless of whether a button is visible or a flag is enabled. Hiding a control in a browser does not protect the underlying operation.

In the example, an authorized account may receive either the existing export or the new filtered export. An unauthorized request receives neither. A disabled flag sends an eligible account to the existing supported path; it must not turn a forbidden request into an allowed one.

Use an account identifier for an account-wide rollout so teammates see consistent behavior. Decide what happens on account switching and missing identity. Avoid putting private targeting rules or secrets in downloadable client code. Our local example uses synthetic IDs only.

Write a flag record before adding the branch

Name the change, the decision being controlled, and the intended lifetime. A temporary release flag should have a removal condition. Record the owner who can change exposure and the person who can respond when the release behaves unexpectedly. Make the old and new paths explicit enough that a reviewer can test both.

Define a fallback for missing configuration and failed evaluation. For our fictional export, preserving the existing supported workflow is safer than enabling an unobserved path. Other features may need a different fallback, especially when an old behavior is no longer valid. Review that choice against the actual product.

Set a review date for cleanup, not an automatic promise that every flag disappears after a fixed number of days. The owner must establish that the chosen behavior is ready to become unconditional and that old code can be removed safely.

An original release record for the fictional export workflow
FieldExample decision
Key and ownerfiltered_export_v1; Engineering owns behavior; Product owns pilot approval
EligibilityAuthorized export users in supported accounts
DefaultExisting export path when configuration is unavailable or the release is disabled
PilotExplicit synthetic internal account, then invited eligible accounts
Stop conditionA permission regression, corrupted export, or unexplained delivery failure pauses exposure
RemovalAfter review of a stable full rollout; remove old path and temporary configuration together

Stage the rollout around decisions you can observe

Start by verifying the new path in a safe test environment, including the disabled state. Enable a designated internal account only after its identity and permissions are correct. Then invite relevant pilot accounts and tell support which behavior they can encounter. A percentage is an exposure mechanism, not evidence of product quality.

Choose the unit of assignment before increasing a percentage. The local example hashes a stable synthetic account ID with a release salt into a bucket from zero through ninety-nine. An eligible account is exposed when its bucket is below the configured percentage. Keeping the salt stable preserves assignment as the percentage grows; changing it can reshuffle accounts.

Decide how you will observe failures, completion, and support reports for the exposed accounts. Record the evaluation outcome and configuration version alongside the relevant operation using only necessary identifiers. A missing observation should prompt investigation before an exposure increase.

  • Exercise enabled and disabled paths, missing configuration, and missing account identity.
  • Confirm permissions with both allowed and forbidden requests.
  • Compare expected and observed exposure using the assignment unit you selected.
  • Ask the release owner to review failures and support reports before each increase.

Use the local example to inspect the decision order

Download the JavaScript module and run node feature-flag-lab.mjs with a supported local Node.js installation. It prints synthetic cases for unauthorized access, unavailable configuration, a targeted pilot, and zero and full percentage exposure. You can read and edit it in a text editor before running it.

The evaluator checks authorization first, then configuration availability and the enabled state, then identity, explicit targeting, and percentage assignment. Invalid percentages use the existing path. The result contains a reason so you can explain which decision applied rather than inferring it from a displayed button.

The example has no network requests, persistence, remote configuration cache, audit service, or user interface. A production integration also needs reliable configuration delivery, consistent identity, appropriate access controls for changing flags, and observability. Follow the chosen provider's current documentation when implementing those parts.

Plan rollback beyond the switch

Turning a flag off can stop future requests from choosing a code path. It does not undo a sent email, delete a queued job, repair a malformed export, or reverse a database migration. Keep the old workflow compatible with any data the new workflow has already written, or prepare a separate recovery plan.

For the example release, review an in-flight export and a retry after the flag is disabled. Decide which behavior an existing job retains and how support can identify it. Make retries safe and prevent an exposure change from duplicating the operation.

A release can also succeed technically while failing to help customers. Use beta feedback to understand the workflow. If you want to estimate the effect of a change, use the assignment, measurement, and analysis discipline in the A/B testing guide; an ordinary staged rollout does not automatically establish a causal result.

Remove the flag when its job is finished

Temporary flags add combinations of behavior, configuration, and tests. After the release review, choose the lasting path, remove obsolete branches and tests, and retire the flag configuration only when the deployed code no longer depends on it. Check background jobs and older application versions before deleting a key.

Keep a short decision note explaining the final behavior and any recovery work. If the flag becomes a permanent entitlement or operational control, rename and document it accordingly rather than pretending cleanup is complete. Review its ownership and failure behavior on that new basis.

The editable record includes eligibility, fallback, rollout stages, stop conditions, a recovery check, and cleanup evidence. Sources and local example checked October 27, 2026.