SPOT TAPE
FRNT-200K2.180+1.42%
MID-128K0.4204−0.81%
OW-70B0.0840+3.11%
OW-8B0.0191+0.44%
VIS-1M1.6400−2.19%
RSN-XL6.9000+0.93%
EMB-S0.01100.00%
14:02:07 UTC
Documentation v1 · UPDATED 21 AUG 2026
Get an API key
On this page

How feature flags work

Feature flags are backed by PostHog and shared across every surface: the Rust gateway, the settlement pipeline, the SDKs, and the dashboard. This page is the authoritative standard — surface-specific tasks cite it for flag names and for where a flag is evaluated. It does not implement evaluation anywhere; each surface owns that.

Naming convention

Every flag key follows <surface>.<area>.<feature>, where surface ∈ {gateway, settlement, sdk, dashboard}. Keys are lowercase, dot-separated, and carry no version numbers — versions belong in PostHog variants, not in the key. The area names the subsystem inside the surface; the feature names the behaviour being gated.

One example per surface:

  • gateway.matching.batch-dispatch
  • settlement.ledger.async-reconcile
  • sdk.retry.adaptive-backoff
  • dashboard.orderbook.depth-chart

A team member can name a new flag for any surface from these rules alone: pick the surface, name the area, name the feature, keep it lowercase and dotted, and leave versioning to variants.

Rollout strategy patterns

Two patterns are supported. Do not invent others.

  • Percentage rollout — release to a growing share of the audience (1% → 10% → 50% → 100%). Backed by PostHog's rollout percentage on the flag. Use it when the change is broadly applicable and you want to observe blast radius before full exposure.
  • User-segment targeting — release to a defined cohort (for example a seller tier, an internal team, or a named account) regardless of percentage. Backed by PostHog release conditions on person/group properties. Use it when the change should reach a specific audience first, such as dogfooding or a design-partner preview.

The two compose: a flag can target a segment at 100% while the general population sits at a lower percentage.

Lifecycle: create → percentage rollout → full rollout → cleanup

  • Create. Entry: a change ready to ship behind a gate. The owning team creates the flag in PostHog under the naming convention, defaults it off, and merges the gated code. Exit: the flag exists and the code path is inert in production.
  • Percentage rollout. Entry: the gated code is deployed and off. The owning team raises the rollout percentage (or enables a target segment) in stages, watching for regressions between steps. Exit: the flag is enabled for its full intended audience with no outstanding regressions.
  • Full rollout. Entry: the flag has held at its full audience without regression through a soak period the team judges sufficient. The behaviour is now the default expectation. Exit: the gated path is confirmed stable and the flag no longer changes anyone's experience.
  • Cleanup. Entry (the exit signal that permits cleanup): the flag has been at stable full rollout with no regression. The owning team removes the flag in PostHog and deletes the dead code branch/gate — the flag check, the now-unreachable branch, and any config it required — so no stale gate or dead path remains. A flag that ships is a flag that gets removed; leaving the gate in place is not a valid end state.

Canary rollback (PostHog metrics driving an automated rollback) is a separate concern; see the canary rollback concept page for that flow.

Where each surface evaluates flags

Each surface evaluates flags at a fixed location so teams pick the right path. Server-side surfaces call the PostHog HTTP API directly; the dashboard uses posthog-js in the browser.

SurfaceWhere it evaluatesHow
Rust gatewayServer-sideDirect PostHog HTTP API via the hyper HTTP/1 client pattern in gateway/src/proxy.rs
Settlement pipeline (ledger)Server-sideDirect PostHog HTTP API inside the consumer loop
Rust token-gateway-sdk and JS/TS SDKsServer-sideDirect PostHog HTTP API
NextJS dashboardClient-sideposthog-js, layered on the PostHogProvider at apps/dashboard/src/components/posthog-provider.tsx