Blog
Explainer

What is a feature flag, and how long until flipping it reaches the user

A feature flag changes behaviour without a deploy. The part most definitions skip is how long the flip takes to reach a user, and which kinds of flag can live with the wait.

Dharmendra Jagodana6 min read

In short

A feature flag is a conditional whose value is set outside your code, so you can change what a user sees without deploying. The question that decides your design is not whether you can flip it but how fast the flip reaches a user. A permission flag can wait for the next page load. A kill switch cannot.

A feature flag is a conditional in your code whose value is set somewhere outside the code, so you can change what a user sees without deploying. Every definition agrees on that much, and it is the easy half.

The half that decides your design is the one most explainers leave out: after you flip the switch, how long until the user actually sees it? Nobody asks until the first time it matters, and the first time it matters is usually an incident.

Why the thing exists

Flags exist to pull deployment and release apart. Without one, the moment code reaches production is the moment customers meet it, so shipping becomes an event: a branch that lives for three weeks, a release window, a rollback plan that is really a redeploy. With a flag, the code goes out dark and the decision to show it is a separate, cheap, reversible act.

That is genuinely one of the better ideas in software delivery. It is also where most writing on the subject stops.

Four types, or four deadlines

The taxonomy everyone borrows comes from Pete Hodgson's feature toggles article on martinfowler.com, revised in 2017. He sorts toggles into four kinds:

  • Release toggles hide unfinished code so it can ship dark.
  • Experiment toggles route cohorts down different paths so you can compare the outcomes, and they have to sit still long enough for the result to mean anything.
  • Ops toggles let whoever is on call disable or degrade something that is misbehaving in production.
  • Permission toggles decide who gets what.

The part that gets copied is the list. The part that gets dropped is that Hodgson sorts them on two axes, and only one of them is longevity. The other is dynamism: how dynamic the decision has to be. That axis is not a footnote. It is the whole engineering problem, and flattening it is how a team ends up buying one mechanism and using it for four jobs.

Read the four again as deadlines instead of purposes:

ToggleFlipped byHow fast it has to land
ReleaseThe team, onceWhenever. Minutes are fine.
PermissionA plan or a listNext page load
ExperimentA bucketing ruleAt assignment, then stable
OpsWhoever is on callNow. Seconds.

Three of those four are relaxed about time. One of them is not, and it is the one you reach for when something is already on fire.

Key takeaway

Ask a flag system how long a flip takes to reach a user, and compare that number against the ops row. If the answer is "next page load", you have a permission mechanism, and you do not have a kill switch.

How a flag actually resolves

A flag is a value that has to get from a console to a running client, and there are only a few ways to move it. Background polling is the common one: the SDK holds the flag set in memory and refetches on an interval. ConfigCat's own explainer, which is the most careful page currently ranking for this term, puts that interval at commonly 30 to 60 seconds and notes that some SDKs add webhook invalidation to shorten it. A pushed connection is faster and costs you a socket. Reading the flag from a store on every request is exact and costs you a round trip per render. Or you can hand the whole flag set over once, when the session loads, and read it from memory after that.

BuildBase picked that last one, and it is worth being specific about the trade because it is the trade this whole post is about. Flags are fetched with the session data and cached locally, so there is no API call per render, and our docs state the consequence plainly: changes take effect on the next page load or session refresh, not instantly for active sessions.

There are two kinds. Workspace features are tied to subscription plans. User features target a user directly, by tag, or through a user or audience list, and four components gate the UI by slug:

<WhenWorkspaceFeatureEnabled slug="advanced-analytics">
  <AdvancedAnalytics />
</WhenWorkspaceFeatureEnabled>

<WhenUserFeatureEnabled slug="beta-editor">
  <NewEditor />
</WhenUserFeatureEnabled>

Map that against the table. Permission toggles: served well, because the deadline is a page load and the mechanism is a page load. Release toggles: fine, nobody is counting seconds. Experiment toggles: we have no bucketing and no percentage ramp, targeting is by user, tag or list, and no built-in conversion analytics either, so you would be tracking the result yourself. Ops toggles: no.

That last one is not a gap we are embarrassed about so much as one worth saying out loud, because the docs say the quiet part too. Disabling a flag hides the gated UI on the next load, and running code is not interrupted. For a plan change that is correct behaviour, and nobody needs an upgrade to appear mid-keystroke. For a kill switch it is the wrong shape, because the request you want to stop is the one already in flight.

When a flag is the wrong choice

When the answer is on your pricing page. A gate that changes because a customer upgraded is not a flag, it is an entitlement, and it should resolve from the plan rather than from a targeting list somebody maintains by hand. The failure here is slow and expensive: a plan changes, most of the flags get updated, and one customer keeps a paid feature for four months. That is the sibling post, entitlements are not feature flags, and the distinction is worth more than it sounds.

When you need it off this second. Covered above. A mechanism that lands on the next page load is not an incident tool, whatever the dashboard lets you click. If you need a real kill switch, it needs its own path.

When the flag has outlived its rollout. A release toggle that survives its release is no longer a flag, it is a branch in your code that nobody owns. Hodgson's longevity axis is the warning: release toggles should be the shortest lived things you have, and the reason teams end up with forty of them is that deleting one is never anybody's job this sprint.

When what you actually want is a role. "Can this person do it" is a permissions question, not a feature question. RBAC owns that, and gating it with a flag gives you an access control system with no audit trail and no concept of a role.

The one next to it

Flags, entitlements and permissions are three gates that look identical at the render site and answer completely different questions. Is the code ready. Did they pay. Are they allowed. Getting them confused is the most common structural mistake in a B2B app, and it shows up as a boolean in a component either way, so nothing warns you.

What entitlements are is the next one to read if the pricing page is the thing your gates keep drifting away from. The propagation argument has a sibling on the permissions side too, where a role change no longer waits for the hourly refresh because an hour was the wrong deadline for that job. Same question as this post, different answer, and that is rather the point: the deadline comes from what the switch is for.

feature-flags
releases
architecture

Frequently Asked Questions

Is a feature flag the same as a feature toggle?

Yes. Feature flag, feature toggle, feature switch and feature gate all name the same mechanism, and the vendors who sell them use the words interchangeably. The only real difference is house style. Pick one word and use it consistently in your own codebase, because a repo that calls the same thing three names is harder to search than it is to explain.

How long does it take for a feature flag change to reach users?

It depends entirely on how the flag is delivered, and this is the number worth asking any vendor for. A flag evaluated from a background poll reaches the user within the poll interval, which ConfigCat puts at commonly 30 to 60 seconds in its own explainer. A flag that rides the session reaches the user on their next page load or session refresh, which has no upper bound while a tab sits open. Push delivery, or a webhook that invalidates the cache, closes the gap to roughly what the network costs.

When should you remove a feature flag?

When it has done its job, which is a question about purpose rather than age. A release flag goes once the feature is stable and nobody would turn it back off. An experiment flag is replaced by the winning variation once the result is conclusive. A permission flag is not temporary at all and stays as long as the plan does, which is why treating every flag as cleanup debt is wrong: some of them are the product.

Are feature flags technical debt?

A flag is not debt. Leaving one behind is. The cost is not the if statement, it is that six months later nobody remembers which of forty switches mean what, so nobody dares delete any of them. The fix is boring and works: give every temporary flag a removal owner and a date when you create it, and make deleting it part of finishing the feature rather than a separate cleanup nobody schedules.

Put this into practice

The modules in this post are one console away. 7-day free trial, no credit card.

7-day free trialNo credit card requiredCancel anytime