Trait-Based Segmentation in Flagsmith

Trait-Based Segmentation in Flagsmith

A complete, plain-English guide to showing the right feature to the right people: what traits are, how segments use them, how rules are evaluated, and how to design, test and run trait-based targeting safely at scale.

Imagine a bakery that makes one special cake every day. On Monday the cake is for children, on Tuesday for people who like chocolate, on Wednesday for customers who have visited more than ten times. The baker does not decide this by guessing. She keeps a small card for every regular customer, with a few facts written on it: age group, favourite flavour, number of visits. When a customer walks in, she glances at the card and knows which cake to offer.

Those little facts on the card are what Flagsmith calls traits. The rule “customers with more than ten visits” is what Flagsmith calls a segment. Put the two together and you get trait-based segmentation: the ability to turn features on, off or change their values for groups of users, based on facts you know about them.

Flagsmith is a tool that lets software teams switch features on and off without releasing new code, using switches called feature flags. A plain flag treats everybody the same. Trait-based segmentation makes a flag smart: the same flag can say “yes” to paying customers, “no” to free users, and “yes, but with a smaller limit” to people on an old version of the app.

In this guide you will learn what traits and segments are, where trait data comes from, how rules are written and evaluated, how to design a clean set of traits, how to test and monitor segments, and how to keep personal data safe. We will use everyday comparisons and examples from well-known companies along the way.

i
Before you start

Flagsmith changes over time. Operator names, plan limits, SDK behaviour and dashboard labels can differ between versions. Treat this guide as the mental model, and confirm fine details in the official Flagsmith documentation for the version or plan you use.

1Why Different Users Need Different Flags

A flag that treats everyone alike is useful. A flag that treats the right people differently is far more powerful.

The limit of a simple switch

A basic feature flag has two answers: on for everybody or off for everybody. That is fine for a quick experiment or an emergency stop. But real products have many kinds of users. Some pay and some do not. Some live in India and some in Brazil. Some use the newest app and some use a version from two years ago. Some are employees testing, and some are customers paying their bills.

If every one of those groups must see the same thing, the team is forced into awkward choices. Either they delay a feature until it is ready for everyone, or they release it to everyone and hope. Neither is comfortable.

What teams really want

Teams want to say things like these, in plain language:

  • “Show the new dashboard only to our own staff for now.”
  • “Give premium customers a higher upload limit.”
  • “Turn off the new payment screen for people on app versions older than 5.0.”
  • “Release the feature in Canada first, because the support team there is ready.”
  • “Let customers who signed up this month try the beta.”

Each sentence mentions a fact about the user: staff or not, plan, app version, country, signup date. Those facts are exactly what traits store.

Analogy

A cinema does not show the same film to everyone in the building. Children go to the cartoon, adults to the thriller, and members get a seat in the quiet screen. The ticket tells the usher which room to send you to. A trait is like information on the ticket, and a segment is like the room.

Benefits in one glance

Safety

Smaller blast radius

A change reaches a small, chosen group first, so a mistake hurts fewer people.

Business

Plan-based features

Entitlements follow the plan a customer pays for, without hard-coding rules in every app.

Speed

No new release needed

Change who sees a feature by editing a rule, not by deploying code.

Learning

Targeted experiments

Test a new idea on one kind of customer and compare it with another.

Support

Gradual rollouts

Support teams meet new questions in small waves, not in one flood.

Compliance

Regional rules

Features can be turned on or off by country where local rules require it.

2Flagsmith Basics: Features, Environments and Identities

Before we add traits, we need to know the parts of Flagsmith that traits attach to.

Organisations, projects and environments

Flagsmith organises everything in three layers. An organisation is usually a company or a team. Inside it live projects, each normally one product. Inside each project are environments, such as Development, Staging and Production. A feature is a named switch defined once per project. What the switch does, whether it is on and what value it carries, is stored separately in each environment.

Remote configuration

A flag can also carry a value, such as a number or a piece of text. This is often called remote configuration. For example, a feature called “upload_limit_mb” might hold the number 25 for ordinary users and 100 for premium users. Segments can change that value for different groups.

What is an identity?

An identity in Flagsmith is a record that stands for one user of your product. It has an identifier, which is a string your system chooses, such as a customer number or a hashed email. Flagsmith uses the identifier to remember that user and give consistent answers across visits.

Identities belong to one environment. The same person has separate identity records in Development and in Production, because the environments are separate rooms.

flowchart TD
    ORG["Organisation"] --> PRJ["Project: Shopping App"]
    PRJ --> FEAT["Features: named switches"]
    PRJ --> SEG["Segments: reusable rules"]
    PRJ --> ENV["Environment: Production"]
    ENV --> FS["Feature states per environment"]
    ENV --> SO["Segment overrides per environment"]
    ENV --> ID["Identities"]
    ID --> TR["Traits: facts about each identity"]
    ID --> IO["Identity overrides"]
Figure 1: Where features, segments, identities and traits live in Flagsmith

A map of ownership

ThingLives atPlain meaning
FeatureProjectThe named switch
SegmentProjectA reusable group defined by rules
Feature stateEnvironmentOn or off, plus value, in one environment
Segment overrideEnvironmentA different setting for one segment in one environment
IdentityEnvironmentOne user record
TraitEnvironment, on an identityOne fact about that user
Identity overrideEnvironmentA special setting for one named user
!
Remember

Segments are written once per project. What a segment does to a flag is decided separately in each environment. That is why a segment can exist everywhere and still affect only production.

3What Is a Trait?

A trait is the smallest and most important building block of targeting. Let us look at it closely.

A plain definition

A trait is a single named fact about an identity, written as a pair: a name and a value. For example: “plan” with the value “premium”, “country” with the value “IN”, “app_version” with the value “5.2.1”, “is_staff” with the value true, or “orders_count” with the value 14.

Analogy

A trait is one line on a library card. One line says “member since 2022”. Another says “favourite section: science”. Together the lines describe a reader, and the librarian uses them to recommend books.

Parts of a trait

  • Key. The name of the fact, such as “plan”. Keys should be consistent and clear.
  • Value. The fact itself. It can be text, a whole number, a decimal number or a true-or-false value.
  • Owner. The identity the fact belongs to.

Traits versus feature values

New learners sometimes confuse traits with flag values. The difference is simple. A trait describes the user and flows from your application to Flagsmith. A flag value describes what the feature should do and flows from Flagsmith to your application. One is the question’s input. The other is the answer’s output.

QuestionTraitFlag value
What does it describe?A userA feature
Where is it set?By your app, backend or the dashboardBy people in the Flagsmith dashboard or API
Which way does it flow?App to FlagsmithFlagsmith to app
Exampleplan = premiumupload_limit_mb = 100
How often does it change?When the user changesWhen the team decides

Examples of useful traits

Account

plan

Free, standard or premium. Drives entitlements.

Place

country

A short country code. Drives regional launches and legal rules.

Software

app_version

The version of the app in use. Drives compatibility rules.

Role

is_staff

True for employees. Drives early access.

Activity

orders_count

How many orders so far. Drives loyalty offers.

Time

signup_month

Month of joining. Drives cohort tests.

!
Keep traits small and safe

Traits are stored and visible to people who can view identities. Do not store passwords, health details or other sensitive personal data as traits. A harmless label such as “premium” is far safer than a detailed personal profile.

4What Is a Segment?

A segment turns facts into groups. It is the reusable “rule of belonging”.

A plain definition

A segment is a named group of users defined by one or more rules. The rules look at traits and decide whether a user belongs to the group. If the facts match, the user is inside the segment. If not, the user is outside. Nobody puts users into a segment by hand. Membership is worked out automatically, every time it is needed.

Examples

  • Premium Users: the trait “plan” is equal to “premium”.
  • India Beta: the trait “country” is “IN” and the trait “beta” is true.
  • Old App Versions: the trait “app_version” is lower than “5.0.0”.
  • Heavy Shoppers: the trait “orders_count” is greater than 10.
  • Staff: the trait “is_staff” is true.
Analogy

A segment is like the rule for entering a members’ lounge at an airport: “holds a gold card or flies business class”. Nobody writes your name on a list. The guard checks your card and ticket each time, and you are in or out depending on the facts.

Why segments are separate from flags

You define a segment once and reuse it across many features. If “Premium Users” appears in twenty flags, and one day the definition changes to include a new plan name, you edit one place. This is the same reason a company keeps one list of departments instead of copying it into every document.

Segments and environments

A segment definition belongs to the project, so every environment sees the same rules. But a segment override is stored per environment. It says: “In this environment, for users in this segment, give this feature this setting.” You can therefore have a segment override for Premium Users in production and none in development.

i
Good to know

Because segment rules are shared by all environments of a project, editing a rule changes who belongs to the group everywhere. Treat edits to segments as project-wide actions.

1
definition of “Premium Users”
N
features that can reuse it
0
users added to it by hand

5Trait-Based Segmentation: Putting the Two Together

Traits supply the facts. Segments supply the rules. Flags supply the behaviour. Here is how the three fit.

The simple formula

Think of the whole system as three steps, repeated whenever an app asks for flags:

1

Know the user

The app tells Flagsmith who the user is, and may send fresh facts about them. These are the traits.

2

Check the rules

Flagsmith compares the traits against each segment’s rules and works out which segments the user belongs to.

3

Apply the settings

For each feature, Flagsmith finds the best matching segment override. If none applies, it uses the default setting.

4

Return the answers

The app receives the on or off state and value of every feature, already personalised for this user.

A tiny example

The upload limit

The feature “upload_limit_mb” has a default value of 25. In production, there is a segment override for the segment “Premium Users” that sets the value to 100. Asha’s identity has the trait plan = premium. When Asha’s app asks for flags, Flagsmith sees that Asha belongs to Premium Users and returns 100. When Ravi, who has plan = free, asks, no override applies and he receives 25.

flowchart LR
    APP["App sends identity and traits"] --> FS["Flagsmith"]
    FS --> EVAL["Compare traits with segment rules"]
    EVAL --> IN{"Inside a segment?"}
    IN -- "Yes" --> OV["Use the segment override"]
    IN -- "No" --> DEF["Use the default feature state"]
    OV --> OUT["Personalised flags returned"]
    DEF --> OUT
    OUT --> APP2["App shows the right behaviour"]
Figure 2: From traits to personalised flags

Why this is better than hard-coding

Without this system, a developer would write rules like “if plan is premium and country is India then show the feature” inside the application. Each change would need a new release, and rules would be scattered across many files. With trait-based segmentation, the code only asks, “Is this feature on for this user?” and all the thinking lives in Flagsmith, where non-developers can adjust it safely.

Analogy

A hotel does not train every staff member on the details of each guest’s room rights. The front desk checks the booking and gives a key that opens exactly the right doors. Segmentation is the front desk, and the flag answer is the key.

6Where Trait Data Comes From

A segment is only as good as the traits behind it. Let us look at all the ways traits reach Flagsmith.

Source 1: The application, through an SDK

An SDK, short for software development kit, is a small helper library that lets your app talk to Flagsmith. When the app asks for flags for a user, it can include traits in the same request. This is the most common route. It is quick and keeps traits fresh, because the app usually knows the latest facts, such as the app version or the language setting.

Source 2: Your backend

Many facts live in your servers and databases: plan, billing status, account age. A backend service can send these to Flagsmith, either when it asks for flags on behalf of a user or whenever a fact changes, for example when a customer upgrades.

Source 3: The dashboard

People can open an identity in the Flagsmith dashboard and add or edit traits by hand. This is useful for testing and for one-off cases. It is not a sensible way to maintain thousands of values.

Source 4: The API and bulk loads

Flagsmith exposes an API for creating identities and setting traits. Teams use it for bulk loads, nightly synchronisation from a customer database, or changes made by scripts.

Source 5: Computed on the spot

Some traits are not stored for long. The app may work them out at the moment of the request, such as the current time of day or the device type, and send them with that one request. Newer versions of Flagsmith support sending such values without saving them, sometimes called transient traits or transient identities. Check your version for how this works.

SourceGood forWatch out for
App SDKDevice facts, version, language, session factsUsers can tamper with data sent from their own device
Backend servicePlan, billing, account facts you trustKeep it in step when facts change
DashboardTesting, special casesManual work does not scale
API or bulk loadSynchronisation, migrationsMass writes can load the system
Computed on the spotShort-lived factsNot remembered for next time unless stored
!
Trust matters

Anything a client app sends can be altered by a determined user. For facts that grant money-related entitlements, such as plan, send the trait from a trusted backend, and consider turning off the environment option that lets client apps set traits. Check the setting name in your version.

Choose one source of truth

For every trait, decide which system is the boss. If the billing system says a customer is premium, then every other system should copy that fact, never invent it. Two sources of truth for one trait produce two answers, and users see odd behaviour.

7Trait Data Types and Naming

Small details about how a trait is typed and named decide whether a rule works or silently fails.

The common types

  • Text. Words and codes, such as “premium” or “IN”.
  • Whole numbers. Counts, such as 14 orders.
  • Decimal numbers. Amounts or scores, such as 4.5.
  • True or false. Yes-or-no facts, such as whether someone is staff.

Why types matter

Imagine a rule says “orders_count is greater than 10”. If one app sends 14 as a number and another sends “14” as text, comparisons may behave differently. Text is compared letter by letter, so the text “9” is larger than the text “10”, because the character 9 comes after the character 1. Flagsmith tries to interpret values sensibly, but you should not rely on that. Pick one type per trait, and always send that type.

Analogy

In a dictionary, “apple” comes before “banana” because words are sorted by letters. If you sorted house numbers the same way, house “9” would come after house “10”. Numbers must be treated as numbers, or the order goes wrong.

Naming rules that save pain

HabitGood examplePoor example
Consistent styleapp_versionAppVersion, appversion, App Version
Clear meaningis_staffflag1
Same spelling everywherecountrycountry, Country, ctry
Standard value formatscountry = INIndia, india, IND, in
Booleans as booleansis_staff = trueis_staff = “yes”

Case and spelling traps

A trait named “Plan” and a trait named “plan” are different traits. A value of “Premium” and a value of “premium” may be different values, depending on the operator used. Pick one style, write it down, and make every app follow it.

i
Tip

Keep a small catalogue, a shared page that lists each trait, its meaning, its type, its allowed values and its source of truth. This one page prevents more bugs than any amount of clever testing.

8Writing Segment Rules

Rules are where traits become decisions. Let us learn how to read and write them.

Anatomy of a rule

A segment is made of rules, and each rule contains conditions. A condition has three parts: a property, which is the trait name; an operator, which is the comparison; and a value, which is what to compare against. For example: property “plan”, operator “is equal to”, value “premium”.

Combining conditions

Rules can combine conditions in three ways:

ALL

Every condition must match

Like “and”. “Plan is premium and country is IN”.

ANY

At least one must match

Like “or”. “Plan is premium or is_staff is true”.

NONE

No condition may match

Like “not”. “Not in the blocked-country list”.

You can also nest rules inside rules, so that “ALL of these, and ANY of those” can be expressed. A segment contains one or more top-level rules, and every top-level rule must be satisfied for the user to belong.

Common operators

OperatorMeaningExample
Equals, not equalsExact comparisonplan equals premium
Greater than, less than, and with or equalNumber comparisonorders_count greater than 10
Contains, does not containPart of a textemail_domain contains example
Matches a pattern (regular expression)Flexible text matchingapp_version matches a pattern
Is set, is not setWhether the trait exists at allbeta is set
In a listMatches any item of a listcountry in IN, BR, US
Percentage splitA stable share of users10 percent of identities
!
Operator availability

The exact list of operators, such as list matching or version-aware comparison, has grown over Flagsmith releases. Check what your dashboard and your SDK versions support before relying on any particular operator.

Three small examples in words

Example A: Premium customers in India

Segment “India Premium”. One rule, ALL of: country equals IN, and plan equals premium.

Example B: Staff or beta testers

Segment “Early Access”. One rule, ANY of: is_staff equals true, or beta equals true.

Example C: Everyone except blocked countries

Segment “Open Markets”. One rule, NONE of: country in the list of blocked countries.

Simple rules are easy to review, easy to test and easy to trust.

9Special Cases: Percentages, Versions and Missing Traits

A few kinds of rules behave differently from the plain comparisons. Knowing them avoids surprises.

Percentage splits

A percentage split rule picks a share of users, such as ten percent, without looking at any particular trait. It is the tool for gradual rollouts: ten percent today, thirty tomorrow, everybody next week. Flagsmith decides membership by turning the user’s identifier into a stable number, so the same user lands on the same side every time. Users do not flicker in and out of the group between visits.

Analogy

Imagine giving every customer a numbered ticket when they join, and saying “tickets 1 to 10 out of 100 get the new menu”. Each person always has the same ticket, so each person always gets the same menu. When you raise the cut to 30, people with tickets 11 to 30 join, and nobody who was already included drops out.

Raising a percentage safely

Because the share is stable, raising it from ten to thirty keeps the original ten inside, and adds twenty more. This is what makes staged rollouts predictable. Lowering it removes users from the top of the range, which may suddenly take a feature away from some people, so plan communication for that.

Percentage splits combined with traits

A percentage rule can sit next to trait rules in an ALL group. For example, “country equals IN, and ten percent of users”. The result is ten percent of Indian users. This is the standard way to roll out regionally and gradually at once.

Versions

App versions look like numbers but are not: 5.10.0 is newer than 5.9.0, though as text “5.9.0” sorts after “5.10.0”. Comparing versions as plain text goes wrong. Newer Flagsmith versions offer a way to mark a comparison as a version comparison, often by adding a short marker to the value, so that version numbers are ordered correctly. If your version supports it, use it for every rule about app or software versions.

!
A classic trap

A rule that says “app_version is less than 5.0.0” can behave badly if both sides are treated as text. Test version rules with real examples, such as 4.9.9, 5.0.0 and 5.10.0, before you trust them.

When a trait is missing

What if a user has no value for a trait, such as a brand-new user without a “plan” yet? Most comparison operators treat a missing trait as not matching. A rule “plan equals premium” will not match. A rule using “is not set” will match. A NONE group may match, because none of its conditions are true. Always ask: “What happens to someone who has no value here?” and test that case on purpose.

RuleUser has plan = premiumUser has plan = freeUser has no plan trait
plan equals premiumMatchNo matchNo match
plan not equals premiumNo matchMatchDepends on version, test it
plan is setMatchMatchNo match
plan is not setNo matchNo matchMatch

Unknown users

Users who have not signed in have no stable identity. You can still serve them flags through the environment’s general settings, or give them a temporary anonymous identifier. Be careful: if the anonymous identifier changes at every visit, percentage rollouts will give them a different answer each time.

10Architecture and Core Components

To trust a system, it helps to know what it is made of. Here are the moving parts behind trait-based segmentation.

The building blocks

Your side

Application and SDK

The place where users meet your product. It asks Flagsmith for flags and may send traits.

Your side

Backend services

The trusted systems that know the facts: billing, accounts, profiles.

Flagsmith

API

The doorway through which apps and people read and change data.

Flagsmith

Database

The durable store for features, segments, identities and traits.

Flagsmith

Evaluation engine

The part that compares traits with rules and decides the answer.

Flagsmith

Read layer and caches

Fast copies near the apps, so flag requests are answered quickly.

flowchart LR
    U["User"] --> APP["App with SDK"]
    BILL["Billing and Account Systems"] --> BE["Backend Service"]
    APP --> API["Flagsmith API"]
    BE --> API
    API --> ENG["Evaluation Engine"]
    ENG --> DB[("Database: features, segments, identities, traits")]
    ENG --> CACHE["Read Cache or Edge Layer"]
    CACHE --> APP
    ADMIN["Team in Dashboard"] --> API
Figure 3: The main components behind trait-based targeting

Two kinds of traffic

Flagsmith handles two very different kinds of work. The first is flag reading: apps asking for flags, constantly, from many users. The second is management: people creating segments, editing rules and changing flags. Management happens a few times an hour. Flag reading may happen millions of times a minute. The two paths are designed to stay apart, so a busy dashboard never slows customers.

Where traits are stored

When an app sends traits with an identity, Flagsmith usually saves them against that identity in its database, so that the next visit starts with the same facts. This is called persisted traits. Server programs that use local evaluation may instead keep identities and traits in their own memory. We discuss that choice in a later chapter.

Analogy

The database is the filing room. The cache is the pile of most-used files on the front desk. The evaluation engine is the clerk who reads a card, checks the rules and says “this customer gets the gold counter”. Customers talk to the front desk, not to the filing room.

11How Evaluation Works Internally

Let us follow a single request from an app, all the way to the personalised answer.

Step by step

1

The app identifies the user

It sends the environment key, the user’s identifier, and optionally a few traits.

2

The key is checked

Flagsmith confirms that the key belongs to a real environment.

3

The identity is found or created

If this identifier is new, Flagsmith creates the record. Otherwise it loads the existing one.

4

Traits are merged

Traits sent in this request are combined with the stored ones. Where both exist, the newly sent value wins, and may be saved.

5

Segments are evaluated

For each segment in the project, the engine checks whether the user’s traits satisfy its rules.

6

Overrides are chosen

For each feature, the engine picks the winning override: a personal override first, then the highest-priority matching segment, then the environment default.

7

Answers are returned

The list of features with their states and values is sent back to the app.

sequenceDiagram
    participant U as User
    participant A as App with SDK
    participant F as Flagsmith API
    participant E as Evaluation Engine
    participant D as Database
    U->>A: Opens the app
    A->>F: Identify user with traits
    F->>D: Load identity and stored traits
    D-->>F: Identity and traits
    F->>E: Merge traits and evaluate segments
    E-->>F: Segments matched and winning overrides
    F->>D: Save updated traits
    F-->>A: Personalised flags
    A-->>U: Shows the right behaviour
Figure 4: One request, from the user opening the app to personalised flags

The order of authority

When several settings could apply to the same feature, Flagsmith picks one using a fixed order. First, an identity override, a special setting for one named user. Second, the highest-priority segment override whose segment matches. Third, the environment default. Understanding this order explains most “why did I get this value?” questions.

Evaluation is repeated, not remembered

Segment membership is worked out every time flags are requested, from the latest traits. It is not stored as a list. This means that when a trait changes, say a customer upgrades to premium, the next request already reflects the new membership. No one needs to move the user between groups.

i
Good to know

Because membership is computed from traits, a segment is not a snapshot. It is a live question that is asked again each time.

12Segment Overrides, Priority and Identity Overrides

A segment on its own does nothing. It needs to be attached to a feature through an override.

What an override says

A segment override reads like a sentence: “For this feature, in this environment, for users in this segment, use this state and this value.” You can attach many overrides to one feature, each with its own segment.

Priority

One user can belong to several segments at once. A Premium user in India may match both “Premium Users” and “India Users”. If both have overrides for the same feature, Flagsmith needs a tie-breaker. Overrides are ranked, and the highest-ranked matching one wins. You can reorder the ranking in the dashboard.

flowchart TD
    START["Feature requested for a user"] --> Q1{"Identity override exists?"}
    Q1 -- "Yes" --> R1["Use the identity override"]
    Q1 -- "No" --> Q2{"Matches the top segment override?"}
    Q2 -- "Yes" --> R2["Use that segment override"]
    Q2 -- "No" --> Q3{"Matches the next segment override?"}
    Q3 -- "Yes" --> R3["Use that segment override"]
    Q3 -- "No" --> R4["Use the environment default"]
Figure 5: How Flagsmith picks the winning setting for one feature

A worked example

PrioritySegmentupload_limit_mb
1 (highest)Staff500
2Premium Users100
3India Users40
DefaultEveryone else25

A premium customer in India matches Premium Users and India Users. Premium has higher priority, so they receive 100. A staff member who is also premium receives 500. A free user in India receives 40. A free user elsewhere receives 25.

Identity overrides

Sometimes you want a special setting for exactly one person: a customer who is part of a pilot, or an executive who wants an early preview. An identity override gives that one identity its own setting for a feature, and it beats every segment. Use it sparingly, since individual exceptions are hard to track and easy to forget.

Order matters, so review it

!
Check the order

A broad segment placed above a narrow one can swallow the narrow one entirely. Put specific segments above general ones, and review the order whenever you add a new override.

Analogy

A club has several discounts. A founder gets half price, a student gets a quarter off, and everyone else pays full price. If a founder who is also a student walks in, the club must say which discount applies. The ranked list is the club’s answer.

13Step by Step: Creating a Trait-Based Segment

Here is the usual path in the dashboard. Labels may vary a little between versions.

Before you begin

  • Decide which fact you will use, and make sure an app or a backend actually sends it.
  • Write the segment name and its purpose in one sentence.
  • Check the trait catalogue for the exact trait name, type and allowed values.
  • Decide which environment you will test in first.

The steps

1

Open the segments area

In your project, open the segments page and choose to create a new segment.

2

Name it clearly

Use a name that says what the group is, such as “Premium Users” or “App Older Than 5.0”. Add a short description.

3

Add a rule

Choose how conditions combine: all, any or none.

4

Add conditions

For each, enter the trait name, pick the operator and type the value.

5

Save the segment

It now exists in the project, available to every environment, but affects nothing yet.

6

Attach it to a feature

Open a feature in the chosen environment, add a segment override, pick the segment and set the state and value.

7

Test with real examples

Check a user who should match and a user who should not, as well as one with a missing trait.

Checking who matches

The dashboard offers ways to look at identities and their traits, and in many versions it can show which identities a segment currently includes, or which segments an identity belongs to. Use these views while testing. They turn a guess into a fact.

i
Tip

Start with the narrowest useful group, such as staff, and widen step by step. Widening is easy. Taking a feature back from thousands of users is not.

14Sending Traits From Your Application

Rules are useless without data. This chapter explains how traits get from your product into Flagsmith, in plain steps without code.

The moments when traits are sent

  • At sign-in. The app tells Flagsmith who the user is and sends the main facts it knows.
  • When something changes. The user upgrades, changes country or finishes onboarding, and the app or backend sends the changed fact.
  • At app start. Facts like the app version and device type are sent each time, since they may change after an update.
  • In the background. A scheduled job copies fresh facts, such as order counts, from your database.

Setting versus reading

SDKs generally offer two different actions. One is “give me the flags for this user, and here are some traits”. The other is “just update this trait”. Choose based on what the screen needs. If the app needs flags anyway, send the traits along with the same request and save a trip.

Removing a trait

To remove a fact that no longer applies, you send the trait with an empty value, which in most versions deletes it. Do this when, for example, a customer cancels a plan. Leaving an old trait lying around means the user may still match old segments.

Keep traits in step with the truth

Event-driven

Update on change

Send the new value when the fact changes. Accurate and quick, but needs hooks in your systems.

Scheduled

Nightly sync

Copy a batch of facts regularly. Simple, but facts can be hours old.

On request

Send with each request

The app sends current facts every time. Always fresh, but relies on the app being honest.

Hybrid

Mix of the above

Trusted facts from the backend, device facts from the app. Common in practice.

!
Do not send too much

Each trait costs storage and a little processing time on every request. Send the handful of facts you really use in rules, not the whole user profile.

Be gentle with writes

If you send the same unchanged traits with every single request, you create many needless writes. Where your SDK allows it, send traits only when they change, or use the option to send short-lived facts without saving them.

15Remote and Local Evaluation With Traits

Flagsmith can decide the answer in two places. Each has strengths and different rules about traits.

Remote evaluation

In remote evaluation, the app asks Flagsmith for the flags of a user, and Flagsmith works out the answer on its servers. Traits are sent with the request or read from storage. This is the default for client-side apps, and it keeps your rules and other users’ data away from the device.

Local evaluation

In local evaluation, a trusted server-side program downloads the whole environment once, including features, segments and overrides, and keeps it in memory. When it needs an answer for a user, it works it out itself, using the traits you supply at that moment. It refreshes the downloaded copy from time to time. This reduces network chatter and can be faster under heavy load.

QuestionRemote evaluationLocal evaluation
Who works out the answer?Flagsmith serversYour own server program
Where do traits come from?Sent with request or stored by FlagsmithSupplied by your program at call time
Are traits saved?Usually yesUsually not, they are used then forgotten
Best forWeb and mobile appsBusy backend services
Key usedClient-side environment keyServer-side key, which must stay secret
FreshnessImmediateAs fresh as the last refresh

The catch with local evaluation

With local evaluation, Flagsmith does not hold the user’s traits unless you also send them there. So if you rely on stored traits, you must supply them from your own systems each time, or the rules will see an empty user. Test this early.

Analogy

Remote evaluation is like phoning the head office for every decision. Local evaluation is like keeping the rulebook on your own desk and checking it yourself. With the rulebook, you also need the customer’s details in front of you, since head office is no longer holding them for you.

Choosing between them

  • Browser and mobile apps: remote evaluation, because the server-side key must never be placed in a device.
  • Backend with high traffic and trusted data: local evaluation is worth trying.
  • Mixed systems: use both, each where it fits.
!
Never ship server keys

The key used for local evaluation can read the whole environment’s rules. Keep it in a secrets manager and only on servers you control.

16Data Flow and Lifecycle of a Trait

A trait has a life: it is born, it changes and it eventually goes away. Planning for each stage prevents stale data.

Stage 1: Birth

A fact first appears, for example when a user signs up. The app or backend sends the first value, and Flagsmith stores it against the identity.

Stage 2: Use

Each time flags are requested, the trait is compared with segment rules. Its value decides which segments the user belongs to.

Stage 3: Change

The user’s situation changes. The new value is sent, and the old one is replaced. From the very next request, the new value drives targeting.

Stage 4: Staleness

If nothing updates the trait when reality changes, it becomes stale. A customer who cancelled a year ago may still be marked premium. This is the most common quiet bug in trait systems.

Stage 5: Removal

The fact no longer applies, or the user leaves. The trait is cleared, and in some cases the whole identity is deleted to meet privacy rules.

stateDiagram-v2
    [*] --> Created: First value sent
    Created --> InUse: Evaluated on each request
    InUse --> Updated: Fact changes and new value sent
    Updated --> InUse
    InUse --> Stale: Reality changed, nothing updated
    Stale --> Updated: Sync catches up
    InUse --> Removed: Trait cleared
    Stale --> Removed: Clean-up
    Removed --> [*]
Figure 6: The life of a trait, including the risk of going stale

Planning for each stage

StageQuestion to answer in advance
BirthWhich system sends the first value, and when?
UseWhich segments rely on it, and who owns them?
ChangeHow fast must a change reach Flagsmith?
StalenessHow do we detect and fix out-of-date values?
RemovalWhen is a trait deleted, and who is allowed to?

Deleting users

Privacy laws in many places give people the right to have their data removed. If identities and traits count as personal data in your setup, you need a way to delete them on request. Plan this early. It is far easier to include deletion in the design than to add it after a request arrives.

17Designing a Clean Trait Schema

A “schema” is just an agreed list of traits and their meanings. A tidy schema keeps a growing company out of trouble.

Start from the questions, not the data

Many teams begin by sending every fact they have, then wonder what to do with it. Do the opposite. List the decisions you want flags to make: who gets early access, which plan unlocks which feature, which regions are ready. Then decide which minimal facts are needed to make each decision.

The catalogue

TraitTypeAllowed valuesSource of truthOwner
planTextfree, standard, premiumBilling systemBilling team
countryTextTwo-letter country codesAccount profileAccounts team
app_versionText, version styleVersion numbersApp at start-upMobile team
is_staffTrue or falsetrue, falseCompany directoryIT team
orders_countWhole number0 and aboveOrders databaseCommerce team
signup_monthTextYear and month, like 2026-10Account systemAccounts team

Principles of a good schema

  • Few and meaningful. Every trait must be used by at least one rule, or removed.
  • Stable names. Renaming a trait means every segment using it must change at once.
  • Coarse rather than precise. “age_group” is usually safer and just as useful as an exact birth date.
  • Derived, not raw. Send “is_premium” or “plan” instead of raw payment details.
  • Documented owners. Every trait has a team that answers questions about it.

Planning change

When you must rename or retype a trait, do it in steps. First send both the old and the new trait. Then update segments to use the new one. Finally stop sending the old one and remove it. Doing it all at once risks a gap where nobody matches any rule.

i
Production habit

Large companies keep an internal registry of user attributes used for targeting, with owners and review dates. Facebook has described a long-running gating system that depends on attributes of users, and the lesson is the same everywhere: the discipline around attributes matters as much as the tool.

18Common Use Cases

Trait-based segmentation solves many everyday problems. Here are the most common ones, with plain examples.

Use case 1: Plan-based entitlements

Features follow the plan

A document tool gives free users three exports a month, standard users thirty, and premium users unlimited. One feature, “monthly_export_limit”, has a default of 3 and two segment overrides based on the trait “plan”. When a customer upgrades, the backend updates the trait, and the next request shows the new limit with no release.

Use case 2: Early access for staff and beta users

Staff first, always

Every new feature is first switched on for the segment “Staff”, defined by the trait “is_staff”. Employees use it for a week and report problems. Later the “Beta Testers” segment is added, based on a trait set when users opt in.

Use case 3: Regional launches

One country at a time

A shopping app launches a same-day delivery option in one country first, using the trait “country”. Support and logistics are ready there. Other countries are added one by one, by editing the segment rule to include more country codes.

Use case 4: Compatibility with old versions

Protect people on old apps

A new payment screen needs app version 5.0 or later. A segment “Old App Versions” uses the trait “app_version” to keep the screen off for older apps, which would crash. When almost nobody remains on the old versions, the segment and the rule can be retired.

Use case 5: Cohort tests

New users only

A team wants to test a shorter sign-up flow. They use a trait “signup_month” and a segment of people who joined this month, so that the test is not mixed with long-time users who already know the product.

Use case 6: Loyalty and behaviour

Reward the heavy users

A segment “Heavy Shoppers”, using the trait “orders_count”, unlocks a free-delivery banner. A nightly job updates the count from the orders database.

Use case 7: Gradual rollouts with safety

Ten percent, then more

A segment with a percentage-split rule exposes a new search page to ten percent of users, then thirty, then everyone. Each step comes with a pause to watch error rates.

Use case 8: Customer-specific behaviour in business products

One customer, one setting

In software sold to companies, every user carries a trait such as “company_id”. A segment per large customer allows special limits or pilot features for that customer’s employees only.

Use case 9: Kill switches for part of the audience

Turn off only where it hurts

A bug affects only one browser type. A segment based on a “browser” trait turns the feature off for that browser, while everyone else keeps it. Much safer than switching it off for the whole world.

The best segments describe a real group that the business can name out loud.

19Segments, Multivariate Flags and Experiments

Segments pair naturally with experiments. Used well, they help teams learn what works for whom.

Multivariate flags

A multivariate flag has several possible values, split by percentages. A button might be blue for fifty percent of users, green for thirty and orange for twenty. A segment override can change these splits for a certain group. For instance, new customers might see an equal three-way split, while long-time customers always see the blue button.

Why segments help experiments

  • Focus. A test about checkout belongs to people who actually reach checkout.
  • Fairness. Comparing new customers with long-time customers mixes two different groups. Segments keep comparisons clean.
  • Safety. Risky variations can be shown first to staff or to a small group.
  • Exclusion. Some groups, such as customers in a sensitive period, can be kept out of tests.

An example

Testing a shorter checkout for new customers

The team defines a segment “New Customers”, where orders_count equals 0. In production, they add an override for the feature “checkout_flow” on that segment, with a multivariate split: half see the old flow, half see the short one. Everyone else keeps the old flow. They compare completion rates only among new customers.

Things to watch

Overlap

Two experiments at once

Users in two experiments may be influenced by both. Keep important tests apart.

Drift

Changing group membership

If a trait changes mid-test, a user may move groups and spoil the comparison.

Size

Groups too small

Tiny segments give noisy results. Make sure the group has enough users.

Analytics

Recording who saw what

Send the variation shown to your analytics tool, or you cannot judge the result.

i
Practice

Big experimenters such as Google and Netflix have written about careful, group-aware testing. The lesson for small teams is simple: decide the group, the change and the measure before you start, and write them down.

20Privacy and Security

Traits are data about people. Treat them with the same care you give any customer data.

Minimise what you send

The safest data is data you never collect. For every trait, ask: “Which rule needs this?” If none, do not send it. Prefer labels over details: “premium” instead of a payment history; “age_group” instead of a birth date.

Avoid direct personal identifiers

Use an internal customer number, or a one-way scrambled form of an email address, as the identity identifier instead of the raw email or phone number. If a trait or identifier leaks in a log or a screenshot, it should not point straight to a person.

Sensitive categories

Never use traits for sensitive information such as health conditions, religion, political opinions or similar categories, unless you have a clear legal basis and strong controls. Many rules place special limits on these. A simple company rule of “no sensitive categories in Flagsmith” avoids a lot of risk.

Who can see what

  • Control who can view identities and traits in the dashboard. Few people need to see them.
  • Use environment settings that hide sensitive values where offered.
  • Give staff the least access they need for their work.
  • Review the access list regularly.

Trust and tampering

Traits sent by a client app can be changed by a clever user. If a trait gives paid features, send it from a trusted backend, and consider disabling client-set traits in that environment. For harmless traits such as the app language, a client is fine.

Analogy

If a shop lets customers write their own discount level on their loyalty card, some will write “platinum”. The shop keeps the real record behind the counter. Traits that matter must be written by the staff, not by the customer.

Keys

The client-side environment key is designed to be visible in apps and only lets them read flags and set limited facts. The server-side key is powerful and must be secret. Store it in a secrets manager and rotate it from time to time.

Rules and laws

Data protection laws in many countries, such as the European GDPR, India’s data protection law and others, care about how personal data is collected, used, stored and deleted. Talk to your privacy or legal team. Show them the trait catalogue, and tell them where Flagsmith is hosted.

Safe habits

  • Few, coarse traits.
  • Scrambled identifiers.
  • Backend-sent entitlements.
  • Limited dashboard access.
  • A way to delete identities on request.

Risky habits

  • Sending the whole customer profile.
  • Raw emails as identifiers.
  • Letting clients set plan traits.
  • Sensitive categories in traits.
  • Everyone has access to identities.

21Performance, Scalability and High Availability

Products with millions of users need targeting that stays fast and stays up. Here is what to think about.

What costs time

For each flag request, Flagsmith must load the identity and its traits, compare them with every segment rule, and choose the override for each feature. A few dozen simple segments are trivial. Hundreds of complicated segments, with many nested rules and heavy text patterns, cost more. Writes also cost: saving traits on each request creates database work.

Millions
flag reads per minute in big products
Dozens
segments in a typical healthy project
Few
trait writes needed per user per day

Ways to keep it fast

Rules

Keep rules simple

Prefer equals and list matches over complex patterns where you can.

Rules

Retire unused segments

Each unused segment is checked for nothing. Delete what you no longer need.

Writes

Send traits only when needed

Avoid saving unchanged values on every request.

Reads

Use caches and edge layers

Let fast read layers answer popular requests close to the user.

Reads

Use local evaluation for heavy servers

Decide on your own server, and save round trips.

Data

Clean old identities

Remove identities of users long gone, to keep the database lean.

Scale out and stay up

The managed Flagsmith service handles scaling for you, using spread-out read layers. A self-hosted installation can run several copies of the API behind a load balancer, with a primary database that has a standby copy ready to take over. The write path for traits tends to be the busiest part, so give the database plenty of room, and watch it as traffic grows.

If Flagsmith has a bad day

Apps should survive a short outage. Give every flag a safe default value in the code. Where possible, let SDKs keep a recent copy of flags so the app can carry on. Decide in advance what each feature does when it cannot learn the answer: for a risky new feature, “off” is normally safest.

!
Segments are not instant magic

Caches mean that a change to a rule can take a few moments to reach every user. Do not design anything that needs every user to switch at exactly the same instant.

22Monitoring, Debugging and Audit

When a user says “I do not see the feature”, you need a fast way to find out why.

The identity page

The Flagsmith dashboard can show the details of an identity: its traits, the segments it currently belongs to and the feature values it would receive. This is the single most useful debugging view. Open the user’s identity, check the traits, and compare them with the segment rules.

A debugging routine

1

Confirm the identity

Is the app sending the identifier you expect? A different identifier means a different person to Flagsmith.

2

Look at the traits

Are the traits present, with the right spelling, type and value?

3

Check segment membership

Does the user belong to the segment you expect? If not, read the rule slowly.

4

Check the override and its order

Is there an override for this feature? Is a higher-priority segment winning?

5

Check the environment

Is the app using the right environment key? A staging key will not see production overrides.

6

Check freshness

Is the app showing an old cached answer? Restart or wait for the refresh.

The audit log

Flagsmith keeps an audit log that records who changed what and when, including edits to segments and overrides. If a group suddenly behaves differently, check whether somebody edited a rule a few minutes earlier. Because segments are shared across a project, one edit can have wide effects.

Useful numbers to watch

  • How many users fall in each important segment, and how that changes over time.
  • How many identities have each trait set, to spot missing data.
  • How many trait writes happen per minute.
  • Error rates in the app after a segment change.
i
Habit

When a segment rule changes, post a short note in your team’s chat or change log. The note should say which rule changed, why, and which features are affected.

23Testing Segments Before They Reach Customers

A segment rule is a small program. Like any program, it needs testing.

Build a test table

For each segment, write down a handful of imaginary users and the answer you expect. Include the normal cases, the edges and the odd ones. Run each through Flagsmith, using test identities in a safe environment, and compare.

Test userTraitsExpected for “Premium India”
Typical matchplan = premium, country = INInside
Wrong planplan = free, country = INOutside
Wrong countryplan = premium, country = USOutside
Missing countryplan = premiumOutside
Wrong caseplan = Premium, country = INDepends on operator, check it
Wrong typeplan = 1, country = INOutside

Use staging that looks like production

Test in a staging environment with the same segments and similar traits as production. Use fake users with names that cannot be confused with real people, such as “test-premium-india-01”. Never test by editing real customers’ traits.

Dry runs for rollouts

Before a big launch, go through the full plan in staging: create the segments, add the overrides, change the percentages and check each step with test users. A rehearsal in a safe space finds mistakes cheaply.

After the change

  • Check a few real identities in production to confirm they land in the expected segments.
  • Watch error graphs and key business numbers for the next hour.
  • Have a one-minute undo plan: for example, disable the override.
Analogy

A theatre runs a dress rehearsal before opening night. Actors wear the costumes and use the props, but the audience is a few friends. A staging test with fake users is a dress rehearsal for a segment.

!
Edge cases cause incidents

Most segment bugs hide in edges: missing traits, uppercase letters, versions with two digits, empty strings and unusual number formats. Put each of these in your test table.

24Advantages, Disadvantages and Trade-offs

No design is perfect. Here is an honest look at what trait-based segmentation gives and what it costs.

Advantages

  • Targeting changes need no new release.
  • Rules live in one place, reusable across features.
  • Smaller blast radius for risky changes.
  • Entitlements follow business facts like plan.
  • Non-developers can adjust groups safely.
  • Supports experiments and staged rollouts.

Disadvantages

  • Depends on accurate, fresh trait data.
  • Many segments become hard to understand.
  • Shared segments make edits risky.
  • Traits are personal data and need care.
  • Extra writes and reads add load.
  • Debugging needs the right views and habits.

Rules in Flagsmith versus rules in code

QuestionRules in codeRules in segments
Changing a ruleNew releaseEdit in dashboard
Who can changeDevelopersAnyone with permission
VisibilityScattered across filesOne list of segments
TestingAutomated testsTest identities and tables
Risk of misuseLower, review by code reviewHigher, needs permission and review habits

Flexibility versus clarity

The freedom to define any segment is also the freedom to make a mess. Teams that enjoy the freedom without discipline end up with hundreds of overlapping segments that nobody understands. A modest list of well-named, well-owned segments is nearly always better than a huge, clever one.

Central rules versus local needs

Shared segments encourage reuse, but one edit touches every feature that uses it. Some teams prefer a few shared segments for company-wide ideas, such as Staff, and private segments for feature-specific needs, with clear names. Use the style that fits your size.

Targeting is power. Power needs a catalogue, an owner and a test.

25Design Patterns and Anti-Patterns

Patterns are habits that other teams have already tested. Anti-patterns are habits that looked clever and then caused pain.

Pattern 1: Staff first

Every new feature goes first to the Staff segment. Employees are forgiving, they know whom to tell, and they find the obvious problems.

Pattern 2: Widening rings

Release in rings: staff, then beta testers, then ten percent, then fifty percent, then everyone. Each ring is one segment or one percentage, and each ring has a pause to watch the numbers.

Pattern 3: Entitlement segments

Create one segment per plan, based on a single trusted trait. Flags attach to these segments for limits and features. The business changes a plan’s rights by editing overrides, not by editing code.

Pattern 4: Compatibility guards

Use an app-version segment to hide features from versions that cannot support them. Pair it with a plan to retire old versions.

Pattern 5: Derived traits

Compute a simple label in your backend, such as “customer_tier”, from many raw facts, and send only the label. Rules stay short, and the complex logic lives in a system built for it.

flowchart LR
    S["Staff"] --> B["Beta Testers"]
    B --> P10["10 percent of users"]
    P10 --> P50["50 percent of users"]
    P50 --> ALL["Everyone"]
    S -.-> W1["Watch and fix"]
    B -.-> W2["Watch and fix"]
    P10 -.-> W3["Watch and fix"]
    P50 -.-> W4["Watch and fix"]
Figure 7: A ring rollout using trait and percentage segments
ANTI-PATTERN 01 Avoid
What it looks like

Dozens of segments with names like “Test2”, “NewSegment” and “Temp Users”.

Why it hurts

Nobody knows what they mean. Features depend on them, and nobody dares to delete them.

Better approach

Clear names, owners and a short description. Review and retire segments every quarter.

ANTI-PATTERN 02 Avoid
What it looks like

The whole customer profile is sent as traits, just in case.

Why it hurts

More personal data, more storage, more risk, and no rule uses most of it.

Better approach

Send only the facts that rules need.

ANTI-PATTERN 03 Avoid
What it looks like

A free-text trait like “notes” or a trait whose spelling differs between apps.

Why it hurts

Rules never match consistently, and bugs are hard to explain.

Better approach

Fixed values from a catalogue, with checks in the sending code.

ANTI-PATTERN 04 Avoid
What it looks like

Client apps set the “plan” trait that unlocks paid features.

Why it hurts

A user can change it and unlock features for free.

Better approach

Set entitlement traits from a trusted backend and restrict client-set traits.

ANTI-PATTERN 05 Avoid
What it looks like

Many individual identity overrides for special people.

Why it hurts

Exceptions pile up, nobody knows why each exists, and they survive long after the reason is gone.

Better approach

Create a named segment for the group, with a clear reason and an end date.

26Best Practices, Common Mistakes and Troubleshooting

Experienced teams build a few simple habits. Beginners tend to make the same few slips.

Best practices

1

Keep a trait catalogue

Names, types, allowed values, source and owner in one page.

2

Choose one source of truth per trait

One system owns each fact. Others copy it.

3

Name segments by meaning

“Premium Users” beats “Segment 7”.

4

Put specific segments above general ones

Priority order should follow common sense.

5

Test edge cases

Missing traits, wrong case, wrong type and odd versions.

6

Roll out in rings

Staff, beta, small percentage, then everyone.

7

Protect personal data

Few traits, coarse values, scrambled identifiers.

8

Review every quarter

Delete unused segments and traits. Check owners and order.

Common mistakes

Mistake

Typo in the trait name

“contry” never matches “country”. The rule silently matches nobody.

Mistake

Number sent as text

Comparisons give strange results.

Mistake

Forgotten missing case

New users without the trait behave unexpectedly.

Mistake

Wrong environment key

Tests run against staging while you edit production.

Mistake

Editing a shared segment casually

Every feature using it changes at once.

Mistake

Stale traits

People keep old plan or country values for months.

Troubleshooting guide

SymptomLikely causeWhat to do
User is not in the expected segmentTrait missing, misspelled or wrong typeOpen the identity, compare each condition with the traits
User gets the wrong valueA higher-priority override winsCheck override order and identity overrides
Change not visible yetCache or SDK refresh delayWait a few moments, refresh the app
Rule works in staging, not productionDifferent traits or overrides per environmentCompare both environments
Percentage rollout flips usersIdentifier changes between visitsUse a stable identifier
Local evaluation ignores stored traitsTraits must be supplied at call timePass the traits from your own systems
Too many writesTraits sent unchanged on every requestSend on change, or use short-lived traits

27Deployment and Cloud: Hosted and Self-Hosted Flagsmith

Where Flagsmith runs changes a few practical details of trait handling.

The hosted service

In the hosted service, Flagsmith runs everything. Scaling, upgrades and read layers close to your users are taken care of. Limits on identities, traits or segments may depend on your plan, so check them before designing a large system.

Self-hosting

Because Flagsmith is open source, a team can run it on its own servers or cloud account. A typical layout has several copies of the API behind a load balancer, a main database with a standby copy, a cache and background workers. Teams choose this path when they must keep data in their own network, or when they want complete control.

flowchart LR
    APPS["Apps and Servers using SDKs"] --> LB["Load Balancer"]
    LB --> API1["Flagsmith API Copy 1"]
    LB --> API2["Flagsmith API Copy 2"]
    API1 --> DB[("Primary Database: identities and traits")]
    API2 --> DB
    DB --> STBY[("Standby Database")]
    API1 --> CACHE["Cache Layer"]
    API2 --> CACHE
    TEAM["Team in Dashboard"] --> LB
    API1 --> WORK["Background Workers"]
Figure 8: A typical self-hosted layout, where identities and traits live in the primary database

What matters for traits when self-hosting

  • Database room. Traits are many small writes. Make sure the database has headroom, and watch its load as users grow.
  • Retention. Decide how long identities are kept, and set up clean-up of old ones.
  • Backups. Identities and traits are real data. Back them up, and practise restoring.
  • Privacy. You are now the data host. Control access, encrypt data in transit and at rest, and record who can see what.
  • Upgrades. After an upgrade, retest a few segment rules, especially those that use newer operators.
Analogy

The hosted service is eating at a restaurant. Self-hosting is cooking at home. Same meal, but at home you are the one who buys the ingredients, keeps the fridge cold and cleans the kitchen.

Regions and data location

Some companies must keep personal data in certain countries. Where Flagsmith runs, and where its database lives, then matters. Ask Flagsmith about the regions of the hosted service, or choose a self-hosted install in the right location. This is a good reason to keep traits minimal.

Cost thinking

The software cost is mainly the plan tier. Indirect costs include database size, the effort to maintain traits and the time people spend managing segments. Tidy habits keep all three low.

28Governance, Ownership and Teamwork

As more teams use Flagsmith, habits matter as much as features. This chapter covers the human side.

Who owns a segment?

Every segment should have an owner, a person or team, and a one-line purpose. Without an owner, nobody knows if a segment can be changed or deleted. Write the owner in the description, and review the list each quarter.

Who owns a trait?

Every trait has two owners: the team whose system is the source of truth, and the teams whose segments depend on it. Changes to a trait’s meaning must be announced to both.

Permissions

Flagsmith lets administrators control who can view and edit things at several levels: organisation, project and environment. Common sense suggests that many people may read segments, fewer may edit them, and very few may edit segments that affect production for large groups. Remember that editing a segment rule changes it for every environment in the project.

RoleSegmentsOverrides in productionIdentities and traits
EngineersView, proposeCreate with reviewView test identities
Product managersViewProposeNo access
Segment ownersEdit own segmentsEdit with reviewView for debugging
Support staffViewNo accessView single identities when needed
AdministratorsSettings onlyRarely editLimited, logged

Review for risky changes

Some plans of Flagsmith offer an approval workflow, sometimes called change requests, where a second person must approve changes to a protected environment before they go live. Use it for production overrides that affect many users. Edits to shared segment definitions are especially worth a second pair of eyes.

A short change note

Whenever you edit a segment or an override, write a short note: what changed, why, who is affected, how to undo. A one-line habit like this makes the audit log and team memory far more useful.

Retiring segments and traits

Spring clean every quarter

Once a quarter, list all segments and all traits. For each, ask: Is it used by any feature? Does it still mean what its name says? Who owns it? Anything unused is deleted. Anything unclear is fixed or renamed. This simple chore keeps targeting understandable.

Teaching newcomers

New teammates should learn in their first week: the trait catalogue, the list of main segments, how priority works, how to debug an identity and who to ask. A one-page guide in plain words, with real examples from your project, is worth more than a long manual.

29A Complete Walkthrough: A Tiered Upload Limit and a Staged Launch

Let us follow a made-up product, “Acme Docs”, through a full project to see how every idea in this guide fits together.

The situation

Acme Docs is a document tool with two million monthly users. It has three plans: free, standard and premium. The team wants to give each plan a different upload limit, and also to launch a new “smart search” page carefully. They use one Flagsmith project with Development, Staging and Production.

Stage 1: Decide the questions

The team writes down the decisions they want flags to make: What upload limit does this user get? Should this user see smart search? From this, they decide which facts are needed: the plan, whether the user is staff, the app version and the country.

Stage 2: Build the trait catalogue

They create a one-page catalogue with four traits: plan (text, from billing), is_staff (true or false, from the company directory), app_version (version style, from the app at start-up) and country (two-letter code, from the account profile). Each has an owner, and the billing team is the owner of plan.

Stage 3: Send the traits

The backend sends plan and is_staff whenever they change, and also at sign-in. The app sends app_version at each launch. The environment option that lets client apps set traits is turned off in production, so that users cannot change their own plan.

Stage 4: Define the segments

SegmentRule
Staffis_staff equals true
Premium Usersplan equals premium
Standard Usersplan equals standard
Smart Search Readyapp_version at least 5.0.0, version style
Smart Search Ring 1ALL of: Smart Search Ready, and ten percent of users

Stage 5: Attach overrides

The feature “upload_limit_mb” has a default of 25, an override of 100 for Standard Users, 500 for Premium Users and 1000 for Staff, ordered with Staff at the top. The feature “smart_search” is off by default. In production, an override turns it on for Staff first.

flowchart LR
    A["Decide questions"] --> B["Write trait catalogue"]
    B --> C["Send traits from billing and app"]
    C --> D["Define segments"]
    D --> E["Add overrides in Staging"]
    E --> F["Test with fake users"]
    F --> G["Copy overrides to Production for Staff"]
    G --> H["Widen to 10 percent, then 50, then all"]
    H --> I["Review and clean up"]
Figure 9: The Acme Docs project from questions to clean-up

Stage 6: Test

In Staging, the team creates ten fake users: free, standard and premium; staff and non-staff; app versions 4.9.9, 5.0.0 and 5.10.0; and one with no plan trait. They check each result against a table of expected answers. They discover that the rule for versions was matching 5.10.0 as older than 5.9.0 because of text comparison. They switch the rule to the version-aware style and retest.

Stage 7: Roll out

In Production, smart search is first on for Staff for three days. Then for ten percent of users who are on a ready app version. The team watches error rates and search success. Everything stays calm. They raise the percentage to fifty and then to everyone over the next week, with a short note in the change log at each step.

Stage 8: Learn and tidy

After the launch, they delete the ring segments and keep the plan segments. They write down lessons: send traits from the backend, test versions, and never skip the missing-trait test. They add these to the team’s checklist.

Worked well

  • One catalogue, with owners and a single source of truth.
  • Plan-based limits changed without any release.
  • The version bug was found in staging.
  • The ring rollout was calm and well recorded.

Could be better

  • The app first sent the version with a stray letter, causing mismatches.
  • One older app never sent the version at all.
  • Nobody had a clear owner for the country trait at first.
DECISION RECORD 01 Accepted
Context

Acme Docs needs plan-based limits and careful feature launches without new releases.

Decision

Entitlement traits are sent only from trusted backends. Segments are based on a small catalogue of named, owned traits. New features go out in rings, beginning with staff.

Consequences

Launch preparation needs more planning, but incidents during launches fall. The team must keep the catalogue current and review segments every quarter.

30Advanced Topics: Nested Rules, Patterns and Trait Hygiene

Once the basics feel comfortable, a few deeper ideas decide how well your targeting ages as the product grows.

Nested rules

A segment can contain rules inside rules. The top level says how the main groups combine, and each inner group says how its own conditions combine. This lets you express sentences such as “country is India or Brazil, and plan is premium or standard, and the user is not staff”. Written out, that is three groups: ANY of two countries, ANY of two plans, and NONE of the staff condition, all required together.

Nested rules are powerful but hard to read. Keep the nesting shallow. If a rule needs more than two levels, ask whether a derived trait, such as “launch_group”, computed in your backend, would say the same thing in one line.

Analogy

A long sentence with many brackets is hard to follow, however correct it is. A short sentence that says the same thing is easy to check and easy to trust. Derived traits turn long sentences into short ones.

Pattern matching with care

Flexible text patterns, often called regular expressions, can match many forms of a value at once. They are also easy to get wrong, slow when complicated, and hard for colleagues to read. Use them only when simple equals or list matching cannot do the job, and always test them against both matching and non-matching examples.

Segments that depend on other segments

Some teams build segments that mirror other segments, such as “Premium Users in India” copied from “Premium Users” with one extra condition. Copies drift apart. When the definition of premium changes, one copy is updated and the other forgotten. Prefer one clear segment per idea, and combine ideas using override order or derived traits instead of copying rules.

Trait drift

Trait drift is the slow growth of differences between what a trait says and what is true. A customer changes country, but the old value stays. A plan is cancelled, but the trait still says premium. Drift quietly gives people the wrong features. Fight it with three habits:

  • Update on change. Wire the source system so that every change sends the new value.
  • Reconcile regularly. Once a night or week, compare a sample of identities with the source system and repair differences.
  • Measure it. Track how many identities disagree with the source. A rising number is a warning.

Identity hygiene

Identities pile up. Every visitor who ever opened your app may have left an identity behind. Many are never seen again. Decide how long unused identities should live, and remove old ones, for both cost and privacy. If your anonymous visitors get a new identifier every visit, you may be creating a new identity for each of them, which fills the database with throwaway records. Prefer a stable anonymous identifier, or use short-lived traits that are not saved.

Versioning your segments

Treat a major change to a segment like a change to an interface. Create a new segment with the new rule, attach it to features beside the old one, check the effect, and then remove the old one. This avoids the surprise of changing a rule that many features quietly depend on.

flowchart LR
    OLD["Old segment in use"] --> NEW["Create new segment with improved rule"]
    NEW --> ATT["Attach new segment to features beside the old one"]
    ATT --> CMP["Compare results with test users"]
    CMP --> SW["Switch overrides to the new segment"]
    SW --> DEL["Delete the old segment"]
Figure 10: Replacing a segment safely, step by step

A worked example: cleaning up a messy project

From sixty segments to twelve

A growing team inherits a project with sixty segments. Some are named after people who left. Several look identical. A few refer to a trait called “Country” while others use “country”. The team starts by exporting the list and marking each segment as used, unused or unknown. Unused ones are deleted in a quiet week, after a final check of the audit log. Duplicates are merged: features that used the copy are re-pointed to the surviving segment, one at a time, with test users confirming each step. The two spellings of the country trait are fixed by sending both for a month, updating every rule, and then stopping the old one. At the end, twelve well-named segments remain, each with an owner, and the trait catalogue finally matches reality. Support staff notice that questions about “why did this user see that?” fall sharply, because every answer is now easy to find.

Questions to ask yourself once a year

  • Do our traits still describe the decisions we need to make?
  • Which segments have not been used in the last six months?
  • How many identities disagree with their source of truth?
  • Would we be comfortable showing our trait catalogue to a privacy reviewer tomorrow?
  • Could a new teammate debug a wrong flag value in ten minutes?
i
A good test of design

If you can explain every segment to a colleague in one sentence, your targeting is healthy. If you need a diagram and ten minutes, simplify it.

31Real-World and Industry Examples

Targeting features by user attributes is a long-standing idea. The descriptions below reflect what these companies have discussed publicly, as patterns, not details of private systems.

Facebook: gates based on user attributes

Facebook has described an internal gating system that decides who sees a new feature using attributes of users, such as whether they are employees, which country they are in and what share of users should be included. New features commonly reach staff first, then small groups, and then larger ones. That is the same ring idea described in this guide.

Netflix: careful, group-aware change

Netflix has discussed testing changes on small slices of its audience before broad release, and comparing the groups with measurements. Group-based testing needs clear, stable groups and good records of who saw what, which is exactly what traits and segments provide.

Google: experiments and launch controls

Google has written about running many controlled experiments and about launch processes that expand a change step by step. Targeting by user attributes, region and device type is a normal part of those approaches.

Uber and similar services: place-based rules

Ride and delivery services operate in many cities, each with different rules and readiness. A trait for the city or region lets a feature be switched on city by city, matching local support and law.

Spotify and subscription services: plan-based features

Subscription products give different features and limits to free and paid users. Driving those differences from a single “plan” fact, rather than from scattered code, is a common design that trait-based segmentation supports.

Software for businesses: customer-specific behaviour

Companies that sell to other companies often turn on pilot features for a single customer. A company trait lets a segment target only that customer’s employees, without creating a separate version of the product.

i
Takeaway

None of these companies treats targeting as an end in itself. They use it to make change safer and more learnable: first for the people who can handle problems, then for more and more users.

4
traits answer most targeting questions
5
rings from staff to everyone
0
new releases needed to widen a ring

32Reusable Checklists

Experienced pilots do not trust memory for routine steps, and neither should you. Copy these into your team wiki.

Before you add a trait

  • Name the rule or decision that needs it. No rule, no trait.
  • Choose a clear name, a type and allowed values.
  • Choose one source of truth and one owner.
  • Check whether it is personal data, and whether you may use it.
  • Decide how and when it will be updated and removed.
  • Add it to the catalogue.

Before you create a segment

  • Write the name, the purpose and the owner.
  • Check that every trait in the rule exists with the right type.
  • Think about users with missing traits.
  • Think about the order among other segments.
  • Prepare a test table with expected answers.

Before you attach an override in production

  • Test with fake users in staging.
  • Check the order of overrides for this feature.
  • Decide the starting group and how it will widen.
  • Write the undo step.
  • Tell the people who need to know.

After a change

  • Open a few real identities and check their segments.
  • Watch error and business graphs for the next hour.
  • Record what changed in the change log.

Every quarter

  • List all segments and traits. Delete unused ones.
  • Check owners and descriptions.
  • Review who can edit segments and see identities.
  • Look for stale traits.
  • Run a test table for the main segments.
Analogy

A tidy workshop has a hook and a label for every tool. These checklists are the hooks and labels for your targeting workshop.

33Plain-English Glossary

A short reference for the words used in this guide.

Term

Feature flag

A switch outside the code that turns a behaviour on or off.

Term

Remote configuration

A value, such as a number or text, that an app reads from Flagsmith.

Term

Environment

A separate set of flag settings for one stage, such as production.

Term

Identity

A record standing for one user, with an identifier.

Term

Trait

One named fact about an identity, such as plan or country.

Term

Segment

A named group defined by rules over traits.

Term

Rule and condition

A rule combines conditions. A condition is property, operator and value.

Term

Operator

The comparison used in a condition, such as equals or greater than.

Term

Segment override

A different setting of a feature for a segment in one environment.

Term

Identity override

A special setting of a feature for one specific identity.

Term

Priority

The order that decides which matching override wins.

Term

Percentage split

A stable share of users chosen by a hashed identifier.

Term

Multivariate flag

A flag with several values split by percentages.

Term

SDK

A software development kit: a helper library for talking to Flagsmith.

Term

Remote evaluation

Flagsmith works out the answers and sends them to the app.

Term

Local evaluation

A trusted server downloads the rules and decides by itself.

Term

Transient trait

A fact used for one request and not saved.

Term

Cohort

A group of users who share a starting point, such as the month they joined.

Term

Audit log

The record of who changed what and when.

Term

Source of truth

The one system that is the boss of a fact.

34Frequently Asked Questions

Quick answers to the questions that come up most often.

Q1What is the difference between a trait and a segment?
A trait is one fact about a user, like plan or country. A segment is a named group defined by rules over traits. Traits are the data, and segments are the decisions made from the data.
Q2Do I have to put users into segments by hand?
No. Membership is worked out automatically from traits every time flags are requested. When a trait changes, membership changes at once.
Q3Can one user be in several segments?
Yes. When more than one segment has an override for the same feature, the highest-priority matching one wins.
Q4Are segments shared across environments?
Segment definitions belong to the project and are shared. Overrides that attach segments to features are set per environment.
Q5Where can I set traits?
From your app through an SDK, from your backend, in the dashboard, or through the API. For facts that grant paid features, send them from a trusted backend.
Q6What happens if a user has no value for a trait?
Most comparisons treat it as not matching. Rules about whether a trait is set or not set behave differently. Always test the missing case.
Q7Why does my percentage rollout keep changing for the same user?
The identifier is probably different at each visit. Use a stable identifier, so the same user always falls on the same side.
Q8Does local evaluation use stored traits?
Typically not. In local evaluation your own server supplies the traits at the moment of the request. Check the behaviour of your SDK and version.
Q9Is it safe to store personal data in traits?
Keep it minimal. Prefer coarse labels, avoid sensitive categories and use scrambled identifiers. Talk to your privacy team and plan how to delete identities on request.
Q10How do I compare app versions correctly?
Use the version-aware comparison if your version supports it, and test with examples like 5.9.0 and 5.10.0. Comparing as text gives wrong order.
Q11What beats what: segment, identity or default?
An identity override comes first, then the highest-priority matching segment override, then the environment default.
Q12How many segments should I have?
As few as you need. A modest list of well-named, owned segments is better than hundreds of overlapping ones. Delete what you do not use.
Q13How do I debug why a user got a certain value?
Open the identity in the dashboard, check its traits and segments, then check override order and the environment you are using.
Q14Are segment features limited by plan?
Limits on segments, overrides and some operators can depend on your plan and version. Check the plan details before designing a large system.

35Summary and Key Takeaways

Let us pull the whole story together in a few lines you can remember.

Key Takeaways

  • Traits are facts, segments are rules. A trait describes one user. A segment turns traits into a named group, worked out automatically each time.
  • Overrides attach groups to features. The winner is an identity override first, then the highest-priority segment, then the default.
  • Data quality decides everything. Use clear names, steady types, one source of truth per trait and fresh values.
  • Test the edges. Missing traits, wrong case, wrong type and versions like 5.10.0 are where bugs hide.
  • Roll out in rings. Staff first, then beta, then a small percentage, then everyone, watching the numbers at each step.
  • Protect personal data. Send few, coarse traits, use scrambled identifiers, and set entitlement traits from trusted backends.
  • Keep it tidy. Own every segment and trait, review them each quarter and verify plan and version details in the Flagsmith documentation.