tier·dev

feature flags for tiered products: a founder's guide

how-to11 june 2026· 6 min read

treat each pricing tier as a named configuration of the same product: every flag has a default, and each tier overrides only what differs. your free edition is 'all defaults', your saas tier flips a handful of flags on, and the diff between any two tiers is readable in one screen instead of scattered across branches.

tiers are configuration, not editions

founders tend to think in editions: the free product, the pro product. engineering then dutifully builds product-shaped containers — separate branches, separate builds, sometimes separate repos. the insight that simplifies everything: a tier is just a set of answers to yes/no questions. is the pro dashboard on? is sso on? is telemetry on?

once tiers are answer-sets, the machinery gets tiny. one codebase asks the questions; each tier's config file holds its answers. adding a new tier — say a 'startup' plan between free and pro — is writing a new column of answers, not standing up a new build pipeline.

defaults and overrides: the two-layer model

the cleanest mental model has two layers. the flag's default state is what any tier gets if you say nothing. overrides are deliberate exceptions per tier. keep defaults conservative — usually off for paid features, on for community features — so a brand-new tier starts safe.

  • default off + override on for saas: the classic paid-feature shape (PRO_DASHBOARD_ENABLED).
  • default on + override off for saas: community-only behaviour, like anonymous telemetry prompts.
  • no override at all: the feature is genuinely universal — and the matrix says so explicitly.

naming and hygiene founders should enforce

flags rot when they're named vaguely and never retired. enforce screaming_snake_case names that state the feature and the verb (SSO_SAML_LOGIN, USAGE_BILLING), require a one-line description, and review the tier matrix monthly. when a flag is on in every tier and the old path is dead, delete the flag and the dead branch of code in the same pr.

the matrix view matters more than any individual flag. it's the artifact you'll share with a new engineer, a prospective acquirer, or your own future self to answer 'what exactly does the paid version add?' — with per-tier resolution, that answer is a screenshot, not an afternoon of code reading.

from matrix to shipped build

tier·dev generates the per-tier config (json, yaml, or a dependency-free typescript snippet) from your matrix. your ci sets PRODUCT_TIER per distribution and the same commit produces every edition. that's the whole trick: tiered packaging as a build input, not a codebase property.

see this on your own repo

tier·dev turns the open-source / saas difference into per-tier feature flags — one repo, generated config, no sdk.

faq

boolean flags only — what about limits like '5 seats'?
start boolean. numeric limits are usually billing-engine concerns, not codebase-divergence concerns. when a number genuinely shapes the build, model it as a flag per threshold (TEAM_SEATS_UNLIMITED) until you need typed values.
how many flags is too many?
teams comfortably run dozens of tier flags. the smell isn't the count, it's flags whose purpose nobody remembers — which descriptions and a monthly matrix review prevent.
can i use this alongside a runtime flag tool?
yes. tier flags decide what a distribution contains; runtime tools decide what an individual user sees right now. plenty of teams run both, and the boundary is healthy.

keep reading

← all guidestry tier·dev