skip to content

When a feature flag has multiple targeting rules, for example always off for free-tier users, always on for internal staff, and a 50% rollout for everyone else, how does a flag evaluation engine typically resolve conflicts between rules, and what architectural trade-offs come from evaluating those rules client-side in a browser or mobile SDK versus server-side?

level: principalimportance: should knowfreq 40%

answer

  1. ordered rules, first match wins
  2. rule order = semantics, not cosmetic
  3. client-side = fast+offline but leaks rules
  4. server-side = private+can see server-only signals but adds hop
  5. hybrid: resolved-only payload to clients

basics

~20 s

Targeting rules are usually checked in order, top to bottom, and the first one that matches a user wins, so rule order matters a lot. Doing that check in the browser or app is fast but exposes your rules and upcoming features to anyone who inspects the app; doing it on your server keeps rules private but adds a network step.

solid answer

~50 s

Most flag engines evaluate targeting rules as an ordered list: each rule is a condition, such as an attribute match or segment membership, plus an outcome, evaluated top to bottom, with the first matching rule winning and a final catch-all percentage-rollout rule if nothing else matches, so rule ordering is itself part of the flag's logic and reordering rules is a behavior change, not a no-op. Client-side (browser/mobile) evaluation ships the full rule set and user-attribute payload to the device, giving instant, offline-capable evaluation but leaking business logic and unreleased-feature existence to anyone inspecting network traffic or app binaries, a real concern for permission flags or embargoed launches. Server-side evaluation keeps rules and unreleased-feature names private and lets evaluation see server-only context such as billing status or fraud signals, but adds a network hop, or requires a nearby evaluation proxy, and centralizes a dependency every request now relies on.

go deeper

for a junior

Should get that when a user matches more than one rule, some order decides which one applies, even without precise terminology.

for a middle

Should describe first-match-wins ordered rule evaluation and name at least one reason client-side flag data could be a privacy or security concern.

for a senior

Should articulate the full client-side vs server-side trade-off, latency and offline capability versus exposure and access to server-only signals, and give a concrete example of information that shouldn't ship client-side.

for a principal

Should discuss hybrid architectures, such as pre-resolved payloads to clients and split SDK behavior by trust boundary, as the real-world pattern platforms converge on, and connect this to broader information-disclosure and embargoed-launch risk management.

## Targeting rules are a small ordered rules engine A targeting rule set turns a flag from a single on/off switch into a small rules engine: each rule pairs a condition with an outcome -- serve variant A, or fall through to the next rule. A condition can be: - An attribute match, such as plan equals enterprise. - A segment membership check, such as user is in the internal-staff segment. - Or a combination. Nearly every production flag platform evaluates these as an ordered list: the engine walks the rules top to bottom for a given user's attributes and returns the outcome of the first rule that matches, falling through to a final catch-all clause, typically the percentage rollout, if no explicit rule matches. This means **rule order is semantically load-bearing**: a "free-tier users always off" rule placed before an "internal staff always on" rule would incorrectly deny an internal staffer who happens to also be tagged free-tier, whereas placing the staff-override first correctly lets it win. Reordering two rules that look independent can silently change behavior for any user who matches more than one, which is why flag platforms treat rule reordering as an auditable change, not a cosmetic edit, and why "which rule wins when several match" is one of the first questions worth asking about any targeting rule set you inspect. ## Why targeting exists at all The reason targeting exists at all, layered on top of a simple percentage rollout, is that real releases rarely want a single uniform slice of users -- they want specific, named cohorts such as: - Internal staff for dogfooding. - A beta customer list. - A geographic region for a compliance-gated launch. - A paid tier for entitlement. Those are combined with a general randomized rollout for everyone else. Building this as a general rule engine rather than one-off code branches means product or support staff can add or adjust cohorts through a dashboard without an engineer writing new conditional code for every new segment. ## Client-side versus server-side evaluation The client-side versus server-side evaluation question is a genuinely consequential architecture decision, not just an implementation detail. | Client-side evaluation | Server-side evaluation | |---|---| | The SDK computes the match locally, in the browser or mobile app | The backend keeps the rule set and the evaluation itself | | Lowest possible latency; keeps working offline using last-known rules | Adds a hop of latency unless cached well; depends on a live, or locally cached-with-sync, service reachable from the server process | | Cost is exposure of rules and flag keys | Keeps rules private; evaluation can use server-only signals | In **client-side evaluation**, the SDK running in the browser or mobile app receives the full rule set for the flags it's configured to know about, along with the current user's attributes, and computes the match locally. This gives the lowest possible latency, since no network round trip is needed at evaluation time, and lets the app keep working using last-known rules even offline. The cost is exposure: a client-side SDK payload, or the rules embedded in a mobile app's local cache, can be inspected by anyone with browser devtools or a decompiled app package, which reveals not just the existence of a flag but its exact targeting logic -- a rule like `if company_domain contains competitor.com then off` is now public knowledge, and worse, the mere presence of a descriptively named flag key in client-shipped config can leak an unreleased feature's existence before launch, an information-disclosure risk that matters a lot for embargoed announcements or entitlement logic a competitor could reverse-engineer. **Server-side evaluation** instead keeps the rule set and the evaluation itself inside the backend, returning only the resolved outcome to the client, or not even that, since the server just behaves differently. This keeps rules private and, just as importantly, lets evaluation use server-only signals that should never ship to a client at all, such as real-time fraud or risk scores, internal account metadata, or billing state pulled fresh from a database, none of which belong in a browser payload. The cost is architectural: every evaluation now depends on a live, or locally cached-with-sync, service reachable from the server process, adds a hop of latency if not cached well, and can't trivially support fully offline client behavior the way an embedded client SDK ruleset can. ## The hybrid platforms converge on In practice, most serious flag platforms support a hybrid: server-side evaluation for anything sensitive, such as unreleased features, entitlement or permission logic, or fraud-adjacent behavior, and client-side evaluation, often via a lightweight already-resolved payload rather than the raw rule set, for latency-sensitive or purely cosmetic UI flags where leaking the logic carries no real cost. A well-known concrete pattern is LaunchDarkly's distinction between server-side SDKs, which can see the full rule set and private context, and client-side SDKs, which by default only receive a pre-filtered set of flags marked available to client-side contexts, specifically to avoid shipping unreleased-feature names or sensitive targeting logic into a browser bundle -- an explicit acknowledgment in the tooling itself that this is a real security and product boundary, not just a performance knob. ## The failure mode in the wild The failure mode this produces in the wild is a predictable one: a team building a mobile-first product defaults every flag to client-side evaluation for simplicity and speed, and months later an unreleased pricing change or an internal-only admin feature's flag key and targeting rules turn up in a decompiled app package or a public bug-bounty report, because nobody drew the line between safe-to-leak and must-stay-server-side at the point each flag was created.

  • If a targeting rule set has a fraud-risk block rule as its last rule, after a 50% percentage-rollout catch-all rule, what's wrong with that ordering?
    Since the percentage rollout is a catch-all checked before the fraud-risk block, most users matching the fraud-risk segment would already be resolved by the rollout rule and never reach the block rule at all, making the block effectively dead logic for that half of matched users. The fraud-block rule needs to move before the catch-all so it's evaluated first and can actually override the rollout outcome.
  • Why might a company deliberately choose server-side evaluation even for a flag that has zero sensitive targeting logic, just a simple 50/50 split?
    If the flag's outcome needs to incorporate server-only signals unavailable to the client, like a fresh database read of account status or consistency with other server-side decisions made in the same request, server-side evaluation is required regardless of how simple the rule looks, since the client fundamentally can't compute the same answer without that data. It may also be a blanket team policy to keep all evaluation server-side for consistency or audit reasons, even at some latency cost.
  • What specific artifact would a security-conscious team worry about auditing when they use client-side flag SDKs?
    The exact payload of flag keys, rule conditions, and default values shipped to the browser bundle or embedded in the mobile app's local config cache, since anyone can inspect network requests or decompile the app to read it. They'd specifically check that no flag marked client-side-available exposes an unreleased feature name, competitor-sensitive targeting logic, or entitlement rules that shouldn't be publicly readable.

Like a bouncer with a numbered list of door policies checked top to bottom, VIP list first, then blocked list, then general cover-charge rule: handing that whole list to every guest to read for themselves (client-side) is fast but tells everyone exactly who's on the VIP and blocked lists, versus keeping the list backstage and just telling each guest in or not (server-side).

saying these in an interview costs you the question

  • Assumes targeting rules are evaluated independently rather than as an ordered, first-match-wins list
  • Thinks reordering targeting rules is always a no-op with no behavior change
  • Doesn't recognize that client-side evaluation exposes rule logic and flag keys to inspection
  • No awareness that server-only signals like billing or fraud scores can't be evaluated client-side without shipping that data to the client
  • Treats client-side vs server-side evaluation as purely a performance choice with no security or privacy dimension

context