GlossaryMay 2, 202612 min readSignaKit

What Are Feature Flags? The Complete Guide

A feature flag is a runtime switch that controls whether a feature is visible to users — without touching your deployment pipeline. Here's everything you need to know: how they work, the 4 main types, and when to use each.

Physical toggle switches representing feature flags being turned on and off

TL;DR

  • A feature flag is a named boolean or multivariate value evaluated at runtime — no redeploy required to change it
  • The SDK fetches flag rules from the cloud, then evaluates them locally in under 1 ms
  • Consistent bucketing via MurmurHash3 ensures users always see the same variant
  • 4 types: release flags, experiment flags, operational flags, permission flags
  • Exposure events are tracked automatically; use trackEvent() for conversion data
  • The free SignaKit plan includes 1 million events per month — flag evaluations are always free

Feature flag (noun): A named configuration value evaluated at runtime that controls whether a feature, behavior, or code path is active for a given user. Also called a feature toggle, feature switch, or feature gate. Feature flags allow teams to change application behavior without modifying or redeploying code.

Every engineering team eventually ships a feature to production before it's ready for all users. Maybe you need to test it with 5% of traffic, or show it only to beta customers, or have a kill switch ready in case something goes wrong. Feature flags are the infrastructure that makes all of this possible — without branching your codebase or gating deploys.

Martin Fowler described feature toggles as “a powerful technique, allowing teams to modify system behavior without changing code.” Since his canonical 2010 article, feature flags have become a core practice at engineering organizations of every size — from two-person startups to teams running hundreds of experiments in parallel.

How Do Feature Flags Work?

A feature flag system has three moving parts: the flag configuration, the SDK, and the evaluation logic.

1. Config Fetching

When your application starts, the SDK fetches a JSON configuration file from a CDN (in SignaKit's case, served from CloudFront/S3). This file contains all flag definitions: which rules apply, which user attributes to target, what the traffic split percentages are, and which variation each bucket maps to.

2. Local Evaluation

All flag evaluation happens in-process — no network call per request. When you call decide() or decideAll(), the SDK matches the user context against the cached rules and returns the decision in under 1 ms. This means feature flags add effectively zero latency to your application.

3. Consistent Bucketing

SignaKit uses MurmurHash3 to deterministically assign users to variations. Given the same user ID and the same flag configuration, the hash always produces the same bucket — so a user who sees the “treatment” variant today will see it tomorrow, even across different sessions or devices.

// lib/signakit/getFlags.ts
import { createInstance } from '@signakit/flags-node'

const client = createInstance({ sdkKey: process.env.SIGNAKIT_SDK_KEY! })

// Wait for initial config fetch
const { success } = await client.onReady()

// Create user context with targeting attributes
const userContext = client.createUserContext('user-abc123', {
  plan: 'growth',
  country: 'US',
  $userAgent: request.headers.get('user-agent') ?? undefined,
})

// Evaluate all flags at once — local, <1ms
const decisions = userContext.decideAll()

// decisions['new-checkout'] => { variationKey: 'treatment', enabled: true, ... }

4. Automatic Exposure Tracking

Every call to decide() or decideAll() automatically fires an $exposureevent in the background (fire-and-forget). This event records which user received which variation, enabling experiment analysis without any manual instrumentation. The backend deduplicates exposure events within a 15-second window per user/flag/page combination, so rapid re-renders don't inflate your event counts.

A deployment pipeline and release flow diagram showing how feature flags fit into the release process

What Are the 4 Types of Feature Flags?

Not all flags are the same. The lifecycle, audience, and purpose differ significantly across these four categories:

TypePrefixPurposeExpected lifetime
Release flagrel_Gradual rollout of a finished featureDays to weeks — delete after full rollout
Experiment flagexp_A/B or multivariate test to measure impactDuration of experiment — delete after winner called
Operational flagops_Kill switch or circuit breaker for live systemsIndefinite — kept as a permanent safety net
Permission flagperm_Entitlement or plan-based feature accessPermanent — evolves with your pricing

Encoding the type in the flag name makes lifetime and cleanup decisions obvious. A flag prefixed exp_ is always temporary; a flag prefixed ops_ is always permanent. For a full treatment of naming, see our guide on feature flag naming conventions.

What Are Common Use Cases for Feature Flags?

Gradual Rollouts

Ship a new feature to 1% of users, watch your metrics, expand to 10%, 50%, then 100% — all without touching the deployment pipeline. If something looks wrong, roll back by flipping the flag off in the dashboard. The change takes effect for new requests immediately.

A/B Testing and Experimentation

Assign users deterministically to control or treatment variants, measure conversion differences, and call a winner at statistical significance. Because bucketing is consistent and exposure events are automatic, you get clean experiment data without complex manual instrumentation. Learn more in our complete A/B testing guide.

Kill Switches

Wrap risky new code paths — payment flows, third-party integrations, infrastructure migrations — in an ops_ flag. If a production incident points to the new code, disable it in 30 seconds without a deploy. This is one of the highest-leverage use cases for feature flags at any team size.

Dark Launches

Deploy new code with the flag off for all users. Run integration tests, measure performance, and validate the implementation in production before exposing it to anyone. Once confident, enable the flag for your team, then beta users, then everyone.

Permissions and Entitlements

Gate features by plan, role, or organization with a perm_ flag. When a customer upgrades, they see new features immediately — no deployment required. This pattern works particularly well for tiered SaaS products where Starter vs Growth vs Enterprise functionality differs significantly.

Feature Flags vs Configuration

Two tools are commonly confused with feature flags:

Environment variablesset infrastructure config at deploy time — database URLs, API keys, region identifiers. They're identical for all users in a given environment and require a redeploy to change. Feature flags change at runtime, per user, without a deploy. Full breakdown: Feature Flags vs Environment Variables.

Hard-coded constants (like const FEATURE_ENABLED = true) need a code change and redeploy to modify. They can't target user segments, can't be changed without engineering involvement, and have no audit trail.

The rule:if you'd ever want to change the value without a deploy, or differently for different users, it's a feature flag — not an environment variable or a constant.

What Are the Key Benefits of Feature Flags?

  • Decouple deploy from release. Shipping code and releasing features to users are two separate decisions. Feature flags let you ship continuously and release on your own schedule.
  • Instant incident response. A kill switch is worth more than any monitoring tool when something breaks in production. Disable the feature in seconds, not the minutes or hours a rollback deployment takes.
  • Data-driven decisions. A/B test features before committing to them. Multi-armed bandit optimization (available on all SignaKit plans) automatically shifts traffic toward better-performing variants.
  • Trunk-based development.Merge feature work to main behind a flag that's off. No long-lived feature branches, no merge conflicts, no integration risk.
  • Safer migrations. Migrate databases, APIs, and infrastructure incrementally with flags as circuit breakers at every step.

Getting Started with SignaKit

Step 1: Install the SDK

npm install @signakit/flags-node

Step 2: Set Your SDK Key

# .env
SIGNAKIT_SDK_KEY=sk_dev_abc123xyz_1234_abcdef123456

Step 3: Initialize and Evaluate Flags

import { createInstance } from '@signakit/flags-node'

const client = createInstance({
  sdkKey: process.env.SIGNAKIT_SDK_KEY!,
})

const { success } = await client.onReady()

const userContext = client.createUserContext(userId, {
  plan: user.plan,
  $userAgent: request.headers.get('user-agent') ?? undefined,
})

const decisions = userContext.decideAll()

// decisions['rel_checkout_v2'] => { variationKey: 'on', enabled: true }
// decisions['exp_pricing_cta'] => { variationKey: 'treatment', enabled: true }

Step 4: Track Conversion Events

// Track a simple conversion
await userContext.trackEvent('signup')

// Track a conversion with value (e.g., revenue)
await userContext.trackEvent('purchase', { value: 99.99 })

// Track with metadata
await userContext.trackEvent('form_submit', {
  metadata: { formId: 'checkout' },
})

SignaKit's free plan includes 1 million events per month. Flag evaluations (decide() and decideAll()) are always free — only automatic $exposure events and trackEvent() calls count toward your limit.

Frequently Asked Questions

What's the difference between a feature flag and a feature toggle?

They're the same thing. “Feature toggle” was the original term popularized by Martin Fowler; “feature flag” became more common in North American engineering communities. Both describe the same concept: a runtime switch that controls feature visibility. See the full comparison: Feature Toggle vs Feature Flag.

Do feature flags add latency to my app?

No meaningfully. The SDK fetches flag rules once at startup, then evaluates all flags in-process. decide() and decideAll() make no network calls — evaluation is a local hash + rule lookup that completes in under 1 ms. Background updates fetch new rules asynchronously, never on the critical request path.

How are users consistently assigned to variants?

SignaKit uses MurmurHash3 on the user ID + flag key combination. This produces a deterministic bucket (0–100) for each user. If a user falls in the 0–10 range for a 10% rollout flag, they always see the treatment — across sessions, devices, and restarts — as long as the flag configuration doesn't change.

What happens if the feature flag service goes down?

The SDK continues evaluating flags against its locally-cached ruleset. If the service is temporarily unreachable, your application uses the last successfully fetched configuration. If the SDK hasn't fetched any configuration yet (e.g., very first startup and the service is down), decide() returns null — your code should always handle the null case and render the default experience.

Are feature flags secure?

Flag configurations (rules, targeting attributes, variation names) are not secret — treat them as public configuration, not credentials. Never put API keys, passwords, or sensitive values inside a feature flag. The SDK key (SIGNAKIT_SDK_KEY) is a server-side secret; keep it in environment variables or a secrets manager, not in client-side code.

Get started free

Add feature flags to your app in minutes

SDKs for React, Next.js, Node, PHP, and Laravel. Free up to 1 million events per month — no credit card required.