Complete Guide

User Targeting in Feature Flags

Show the right features to the right users at the right time. Learn how targeting attributes, segments, and rollout rules combine to give you surgical control over every release.

8 min read·Last updated March 2026
01 · Foundations

What is user targeting?

User targeting lets you evaluate a feature flag differently for different users. Instead of a global on/off switch, you get surgical per-cohort control.

A simple boolean flag is a kill-switch. A targeted flag is a policy. You define rules that map user context (attributes your application knows about the current user) to a flag value.

Supaship supports two evaluation modes. With local evaluation, the SDK fetches the full ruleset from the edge once and evaluates rules in-memory on every call. With edge evaluation, the SDK sends context to the edge and receives only the result. Both modes use the same targeting rules you define in the dashboard.

Targeting evaluation · same flag, different userscheckout-v2

Flag rules (evaluated top-down)

Rule 1plan == "pro"true
Rule 2email contains "@acme.com"true
Rule 325% of remaining userstrue
Defaulteveryone elsefalse

User evaluations

usr_alice
plan=proemail=[email protected]
Rule 1true
usr_bob
plan=freeemail=[email protected]
Rule 2true
usr_carol
plan=freeemail=[email protected]
Rule 3true
usr_dave
plan=freeemail=[email protected]
Defaultfalse
Rules are evaluated locally (after ruleset fetch) or at the edge — same targeting logic either way
02 · Attributes

Targeting attributes

Any key-value pair your application knows about a user can be a targeting attribute. Pass them in the context object at evaluation time — no schema required.

Category
Attribute
Example value
When to use
Identity
userId
"usr_abc123"
Stable per-user targeting and cohort consistency for percentage rollouts
email
Domain-based targeting (e.g. all @acme.com users) or specific user overrides
accountId
"acc_enterprise"
Account-level rollouts for B2B products — same flag value for all users in an account
Plan
plan
"pro" | "free"
Tier-gated features and upsell paths — show Pro features only to paying users
trialDaysLeft
14
Trial-expiry nudges and contextual upgrade CTAs based on remaining trial days
mrr
299
High-value account targeting — unlock white-glove features above an MRR threshold
Location
country
"DE"
Regulatory feature gating (GDPR, DMA) or country-specific product behaviour
region
"us-east-1"
Geographic rollouts and data-residency compliance per cloud region
timezone
"Europe/Berlin"
Time-sensitive feature windows — only show during business hours in a timezone
Behaviour
signupDaysAgo
7
Separate onboarding for brand-new users from veterans who already know the product
lastActiveAt
"2026-03-01"
Re-engagement campaigns — show win-back UI only to dormant users
totalSessions
42
Power-user detection — unlock advanced features after sufficient usage

Custom attributes

Pass any attribute in the context object — the SDK forwards whatever you include. Common examples: betaOptIn, companySize, salesforceId, abTestGroup. With local evaluation they are bundled into the cached ruleset; with edge evaluation they are sent as part of the context on each call.

03 · Segments

Segment targeting

A segment is a reusable audience definition. Define it once, use it across many flags.

Without segments, every flag that targets enterprise users needs to duplicate the same rules: plan = enterprise AND mrr > 500. Change the definition once and you have to update every flag.

Segments fix this. Define "Enterprise customers" once, reference it from any flag. Update the segment definition and all flags that use it stay in sync automatically.

S
Enterprise customers
plan = enterprise
14
flags
S
Beta testers
betaOptIn = true
7
flags
S
EU users
region = eu OR country in [DE, FR, NL, SE]
5
flags
S
New signups
signupDaysAgo < 7
3
flags
Rule builder · new-ai-sidebar flag
RULE 1 · always enabled
SegmentEnterprise customers→ true
RULE 2 · percentage
SegmentBeta testers50%→ true
DEFAULT
All other users→ false

Rules evaluate top to bottom, first match wins

1.Enterprise customer with betaOptIn=false → Rule 1 matches → true
2.Beta tester with userId hash in 50% → Rule 2 matches → true
3.Free user, no match → Default → false
04 · Percentages

Percentage rollouts & consistency

A percentage rollout should give the same user the same result on every request, not a random coin flip each time.

The SDK uses a consistent hash of the user identifier to determine bucket membership. This means:

Same user, same result
usr_alice always falls in the same percentage bucket, session after session, server to server.
Monotonic expansion
Increasing from 10% to 25% includes all existing 10% users plus a new cohort. Existing users never get their experience toggled unexpectedly.
Flag-level salt
Each flag uses a unique salt in its hash so that a user in the "enabled" bucket for flag A is not predictably in the same bucket for flag B.
Consistent hashing · 25% rollout
usr_alice
0.08
true
usr_bob
0.22
true
usr_carol
0.31
false
usr_dave
0.67
false
usr_eve
0.19
true
Users with hash < 0.25 (the dark zone) receive true. The hash is deterministic: the same userId + flagKey always produces the same value.
05 · In Supaship

User targeting in Supaship

Supaship gives you a visual rule builder, reusable segments, and a percentage rollout slider — all wired to the same evaluation engine your SDK calls.

1

Build rules visually

Define conditions using any context attribute — no code required. Combine conditions with AND / OR logic, pick an operator, and set a value. Rules evaluate top-down and short-circuit on first match.

IFemailcontains"@acme.com"→ true
OR IFcountryis one of"France", "Ireland"→ true
ELSE25% of remaining users→ true
DEFAULT→ false
Visual rule builder in the Supaship dashboard
Segment list and editor in Supaship
2

Reuse segments across flags

Define an audience once as a named segment and reference it from any flag rule. Update the segment definition and every flag that uses it stays in sync automatically.

  • Named segments with AND / OR conditions
  • Reference segments directly in flag rules
  • One update syncs across all dependent flags
  • Combine segment match with a percentage rollout
3

Gradual rollout with sticky bucketing

After your targeting rules, set a percentage for the remaining audience. Supaship uses a consistent hash of the user ID so the same user always lands in the same bucket — no flickering, no surprises.

  • Adjust percentage without redeploying
  • Expanding percentage never excludes existing users
  • Each flag uses a unique salt for independent bucketing
  • Set to 0% as an instant kill-switch
Percentage rollout slider in Supaship
Flag evaluation test results showing rule match breakdown
4

See which rules matched

The rule evaluation preview lets you simulate any user context directly in the dashboard — no code, no deploys. Set user properties, system conditions, and hit Test Rule Evaluation to see exactly which rule matches and what value would be returned.

Rule Evaluation Preview

Simulate user context to preview rule matching

Country
United States of America (US)
Region
North America (NA)
Browser
Chrome
OS
iOS
Device Type
Desktop / Laptop
IP Address
192.168.1.1
Test Rule Evaluation
06 · Code

SDK integration in your application

Pass user context to the SDK at evaluation time. Attributes are evaluated against the cached rules and discarded, never stored.

import { SupaClient, FeaturesWithFallbacks }
  from '@supashiphq/javascript-sdk'

const features = {
  'ai-sidebar':    false,
  'new-nav':       false,
  'quick-search':  false,
} satisfies FeaturesWithFallbacks

const client = new SupaClient({
  apiKey:      process.env.SUPASHIP_API_KEY!,
  environment: 'production',
  features,
  context: {
    userId:        user.id,
    email:         user.email,
    plan:          user.subscription.plan,
    region:        user.region,
    signupDaysAgo: daysSince(user.createdAt),
    betaOptIn:     user.settings.betaOptIn,
  },
})

// Batch fetch — single network call
const flags = await client.getFeatures([
  'ai-sidebar', 'new-nav', 'quick-search',
])

if (flags['ai-sidebar'])   renderAiSidebar()
if (flags['new-nav'])      renderNewNav()
if (flags['quick-search']) enableQuickSearch()

Performance

All flags fetched in a single getFeatures() call
Ruleset cached in-memory after first fetch
Rules refresh in background via SSE push
Context attributes are never stored server-side
Node.js · per-request context override
app.get('/dashboard', async (req, res) => {
  const enabled = await client.getFeature(
    'dashboard-v2',
    {
      context: {
        userId: req.user.id,
        plan:   req.user.plan,
      },
    }
  )

  res.render(
    enabled ? 'dashboard-v2' : 'dashboard'
  )
})
Update context on login
// Update targeting context when user logs in
function onUserLogin(user) {
  client.updateContext({
    userId: user.id,
    email:  user.email,
    plan:   user.plan,
  })
}

// All subsequent getFeature() calls will
// use the updated context automatically

Get started

Target your first segment in minutes

Supaship supports unlimited targeting attributes, reusable segments, and rule operators, free to start.