Skip to main content

Feature Flags

Feature flags allow EGI to deploy code to production without exposing it to all users. They enable controlled rollouts, A/B testing, beta programs, and safer deployments. EGI uses PostHog for feature flag management.

When to Use Feature Flags

Feature flags are appropriate in the following situations:

ScenarioExample
Gradual rolloutRolling out a new dashboard to 10% of users, then 50%, then 100%
Beta testingGiving a specific list of users early access to a feature
Kill switchAbility to disable a feature instantly in production without a deployment
A/B testingComparing two implementations of a feature to measure which performs better
Client-specific featuresEnabling functionality for one client but not others in a multi-tenant product
Incomplete featuresMerging work-in-progress code to main behind a flag to avoid long-lived branches

When Not to Use Feature Flags

  • Configuration values that change per environment (use environment variables instead)
  • Permanent feature toggles that will never be removed (use role-based access or product tiers instead)
  • Secrets or sensitive logic (flags are client-readable; do not gate security controls behind flags)

Naming Conventions

Feature flag names use snake_case and follow this structure:

[scope]_[feature_name]
ComponentDescriptionExample
scopeThe area of the product the flag affectsdashboard, onboarding, billing, api
feature_nameA short, descriptive name for the featurenew_chart_view, guided_setup, bulk_export

Examples:

  • dashboard_new_chart_view
  • onboarding_guided_setup
  • billing_annual_plan
  • api_v2_endpoints

Rules:

  • Always use snake_case (no hyphens, no camelCase)
  • Keep names under 50 characters
  • Be specific enough that the flag's purpose is clear without looking up documentation
  • Never include dates, ticket numbers, or developer names in flag names

Flag Types in PostHog

Boolean Flags

The simplest type. The flag is either on or off.

if (posthog.isFeatureEnabled('dashboard_new_chart_view')) {
return <NewChartView />
}
return <LegacyChartView />

Use boolean flags for: kill switches, simple rollouts, and feature gating.

Multivariate Flags

The flag returns one of several string values, allowing you to test multiple variants.

const variant = posthog.getFeatureFlag('onboarding_flow_variant')

switch (variant) {
case 'control':
return <StandardOnboarding />
case 'streamlined':
return <StreamlinedOnboarding />
case 'guided':
return <GuidedOnboarding />
}

Use multivariate flags for: A/B/n tests and experiments with more than two options.

Rollout Strategies

Percentage Rollout

Gradually increase the percentage of users who see the feature.

Recommended rollout schedule:

StagePercentageDurationAction
Canary5%1--2 daysMonitor for errors and unexpected behavior
Early rollout25%3--5 daysCheck analytics for engagement and performance
Broad rollout50%3--5 daysConfirm no regressions at scale
Full rollout100%--Flag cleanup begins

At each stage, check the following before advancing:

  • No increase in error rates
  • No performance degradation
  • User behavior metrics are stable or improving
  • No negative feedback through support channels

User Targeting

Enable the feature for specific users or user groups.

Common targeting criteria:

  • Internal team -- Flag enabled for EGI and Anchor team members for internal testing
  • Beta users -- Flag enabled for a specific list of user IDs who opted into the beta program
  • Client-specific -- Flag enabled for users belonging to a particular organization or account
  • Role-based -- Flag enabled for users with a specific role (e.g., admins only)

Configure targeting in PostHog using person properties set during user identification.

Beta Programs

For features with a formal beta program:

  1. Define beta criteria and communicate them to the client or user group
  2. Create the feature flag with user targeting for beta participants
  3. Collect structured feedback (survey, Slack channel, or SuiteDash form)
  4. Review feedback at the end of the beta period before proceeding to a broader rollout
  5. Document beta findings and any changes made based on feedback

Implementation Guidelines

Server-Side vs. Client-Side

Evaluation LocationWhen to UseHow
Client-sideUI changes, frontend features, non-sensitive gatingposthog.isFeatureEnabled('flag_name') in React/JS
Server-sideAPI behavior, data processing logic, security-sensitive featuresposthog.isFeatureEnabled('flag_name', distinctId) via posthog-node

Default Behavior

Always define a sensible default for when a flag evaluation fails (e.g., PostHog is unreachable):

const showNewFeature = posthog.isFeatureEnabled('dashboard_new_chart_view') ?? false

The default should be the safe, existing behavior (typically false / feature off).

Avoiding Flag Nesting

Do not nest feature flags (checking one flag inside another). Nested flags create complex state combinations that are difficult to reason about and test. If you need compound logic, create a single flag with multivariate values instead.

Cleanup Policy

Feature flags are temporary by design. Leaving stale flags in the codebase increases complexity and makes the code harder to maintain.

Cleanup Timeline

  • 30 days after full rollout (100%): The flag must be removed from the codebase
  • The developer who created the flag is responsible for cleanup
  • Cleanup is tracked as a chore ticket created at the time the flag reaches 100% rollout

Cleanup Process

  1. Confirm the flag has been at 100% for at least 30 days with no issues
  2. Remove all conditional logic in the codebase that references the flag
  3. Remove the fallback/legacy code path that is no longer used
  4. Delete or archive the flag in PostHog
  5. Submit a PR with the cleanup changes, referencing the original flag and feature

Tracking Stale Flags

During the quarterly documentation review, audit all active feature flags:

  • Identify any flags that have been at 100% rollout for more than 30 days without cleanup
  • Identify any flags that have been active for more than 90 days total (may indicate a flag being used as permanent configuration)
  • Create cleanup tickets for any stale flags found

Best Practices Summary

  1. Keep flag lifespans short. Flags are temporary; plan for removal from the start.
  2. Test both states. Always test the feature with the flag on and off before merging.
  3. Monitor after each rollout stage. Do not advance rollout percentages without checking metrics.
  4. Document the flag. Add a brief description in PostHog when creating the flag so others understand its purpose.
  5. One flag per feature. Do not reuse a flag for multiple unrelated features.
  6. Default to off. New flags should default to disabled and be explicitly enabled through PostHog.