Webclat / PostHog Practice

Keeping one feature flag consistent across every PostHog project

A flag that needs to behave identically in a web app, a mobile app, and a staging environment run as separate PostHog projects is a different problem than a single-project rollout - it needs one definition managed in one place, not three flags kept in sync by hand.

Why multi-project flags are a distinct problem

Teams running separate PostHog projects per environment or per product surface (common for staging/production separation, or for multi-product companies) hit a specific failure mode: a flag created independently in each project drifts - different rollout percentages, different targeting rules, someone forgets to update one of them. Multi-project flag management exists to give a flag one canonical definition that propagates, rather than depending on manual discipline across every project.

Implementation done properly

PieceWhat it's forWhat to get right
Multi-project flag definitionOne flag, consistent rollout/targeting logic across the linked projectsDecide which projects actually should share a flag versus which need independent control - not every flag belongs in this category
Flags APIProgrammatic flag evaluation and management outside the PostHog UI - CI/CD gating, server-side evaluation, custom toolingAPI-evaluated flags need the same naming and ownership discipline as UI-managed ones, or the two drift apart
VS Code extension flag managementChecking or toggling flag state without leaving the editor, useful during active feature developmentConvenient for individual developer workflow; not a substitute for a documented rollout process at the team level
Documented use casesPostHog's own feature-flag use-case patterns (kill switches, gradual rollouts, permissioning) as a reference for what a flag is actually for before creating oneA flag created without a defined use case in mind is the first candidate for becoming permanent technical debt

Exposure: confirming the flag is actually doing what you configured

Exposure tracking (recording which users actually evaluated a flag and which variant they received) is what lets you distinguish "the flag is configured for 20% rollout" from "20% of the relevant population has actually been exposed to it" - those are not automatically the same number if evaluation is gated behind another condition, or if a code path evaluates the flag inconsistently.

How to verify it worked

  1. Confirm the flag evaluates identically across all linked projects for a matching test user/context - a multi-project flag that returns different values per project defeats the purpose.
  2. For API-evaluated flags, check that a server-side evaluation and a client-side evaluation for the same user return the same variant, unless intentionally configured otherwise.
  3. Pull exposure data after rollout and compare it against the configured rollout percentage - a material gap usually means the flag is gated behind a condition (a feature check, an environment check) that is filtering who gets evaluated at all.
  4. Confirm flag changes made via the VS Code extension or API show up identically in the PostHog UI - a management surface that is out of sync with the source of truth is worse than not having it.

Frequently Asked Questions

Do all flags need to be multi-project?

No - most flags are scoped correctly to a single project. Multi-project flags solve a specific problem (the same flag needing identical behavior across environments or products) and add coordination overhead that is not worth it for a flag that only ever needs to exist in one place.

What's the difference between exposure and rollout percentage?

Rollout percentage is the configuration; exposure is the measured reality of who actually evaluated the flag. They should track closely - a persistent gap is a signal that something upstream of the flag check is filtering the population, not a flag-configuration problem.

Get flag management that scales past one project.

We design the multi-project flag structure, API evaluation contract, and exposure tracking before drift sets in - not after three projects disagree about the same flag.

Design My Flag Structure