Segment Rules and Conditions in Flagsmith

Segment Rules and Conditions in Flagsmith

A complete, plain-English guide to deciding exactly who sees what: how segments are built from rules and conditions, how every operator behaves, how overlapping audiences are resolved, and how to test, debug and maintain targeting that stays correct as your product grows.

Picture a new feature that is ready, but not for everybody. You want your own staff to see it first. Then perhaps customers on the premium plan in one country. Then a quarter of everyone using the latest version of your mobile app. Each of those sentences describes an audience, and each audience is described by a few simple facts about the people in it: who they work for, which plan they pay for, where they live, which version they run. Turning those facts into a precise, reusable definition is the job of segments, and the building blocks inside segments are rules and conditions.

Flagsmith is an open-source feature flag and remote configuration service. Its segments let you describe an audience once, then use that description on as many flags as you like. A segment is only as good as its rules, though. A misplaced operator, a trait spelled slightly differently in two apps or an unexpected empty value can quietly send a feature to the wrong people. The details matter, and they are easy to learn when they are explained in order.

This guide starts with the very first idea, what a segment is, and builds up to the full set of operators, nested rule groups, percentage splits, evaluation order, testing habits, privacy care and long-term maintenance. No prior knowledge of Flagsmith is assumed, and no code is needed to follow along. Menu names and some options vary between versions and plans, so treat the screens described here as signposts and confirm the exact wording in your own dashboard and in the official documentation.

1Why Audience Rules Exist

A feature flag with only an on and off position is a blunt tool. Segments make it precise.

What is a feature flag, briefly?

A feature flag is a switch in your application that decides whether some behaviour is active. The code for a new feature is shipped, but it stays hidden until the flag is turned on. The decision lives in a service such as Flagsmith, outside your code, so changing it needs no new deployment. This separates deploying code from releasing a feature, which is the single biggest reason teams adopt flags.

The problem with “everyone or no one”

A plain switch has two outcomes. Everyone gets the feature, or nobody does. That is rarely what a real release needs. New features are risky, so you want a small, friendly audience first. Some features belong only to paying customers. Some should appear only in countries where you have a legal licence. Some should be hidden from people running an old app version that cannot display them. Each of these is a question about who the user is, not just a question about whether the feature is ready.

What is a segment?

A segment is a saved description of a group of users, built from facts about those users. You give it a name, such as “premium customers in India”, and you describe the group using rules. From then on, Flagsmith can answer a simple question for any user: do you belong to this group or not? Flags can then behave differently for members of the group, which is called a segment override.

Everyday analogy

Think of a members-only club with a doorkeeper. The doorkeeper has a written list of entry rules: over eighteen, holds a gold card, and either lives in the city or is a guest of a member. Each visitor is checked against the list, and the doorkeeper says yes or no. The rule list is the segment, each line on the list is a condition, and the club’s different rooms, which treat members differently, are the flags with segment overrides.

Why define the group once?

You could, in theory, write the audience rules separately on every flag. That would quickly become a mess. If the definition of “premium customer” changes, you would have to hunt through dozens of flags to update each copy. A segment solves this by keeping the definition in one place. Change the segment, and every flag that uses it follows automatically. This is the same reasoning that makes programmers put repeated code into one shared function.

Real-world example: Facebook’s Gatekeeper

Facebook has publicly described an internal system called Gatekeeper that decides which users see which features, based on rules about users such as their employment, location or a percentage of the population. The idea of keeping rules about people separate from the features themselves, and changing them without redeploying code, is exactly the approach segments bring to ordinary teams.

i
Tip

Describe every segment in business words, such as “trial customers” or “internal staff”. When someone reads a flag’s override list months later, a name that explains itself saves a trip into the rules.

2The Vocabulary: Eight Words You Need

Almost everything in targeting uses the same few terms. Learn them once and the rest of this guide reads smoothly.

The person

Identity

A single user as your application describes them to Flagsmith, usually with a unique identifier such as an account number or email-free user ID.

A fact

Trait

A named piece of information about an identity, such as plan, country or app_version. Traits are what rules look at.

The group

Segment

A named, reusable audience definition made of rules, defined once at the project level.

The wrapper

Rule

A container that groups conditions and says how they combine: all of them, any of them or none of them.

The test

Condition

One check, made of a property, an operator and a value, such as “plan equals premium”.

The comparison

Operator

The kind of comparison a condition makes: equals, greater than, contains, is set and others.

The consequence

Segment override

A setting on a flag, in one environment, that says what members of a segment should receive.

The order

Priority

The ranking of a flag’s overrides, used to decide which one wins when a user belongs to several segments.

flowchart TD
    SEG["Segment: Premium customers in India"] --> R1["Rule group 1: ALL of the following"]
    SEG --> R2["Rule group 2: ANY of the following"]
    R1 --> C1["Condition: plan equals premium"]
    R1 --> C2["Condition: country equals IN"]
    R2 --> C3["Condition: app_version at least 4.2.0"]
    R2 --> C4["Condition: platform equals web"]
    SEG -. "used by" .-> OV["Segment override on a flag in one environment"]
FIG 1 · The anatomy of a segment: rule groups hold conditions, and flags use the segment through overrides

Read the figure from the top. One segment holds one or more rule groups. Each rule group holds conditions and states how they combine. Every condition is a single test about a trait. The dotted arrow at the bottom shows that a flag uses the whole segment through an override, so the flag never needs to know how the audience was built. This layering is what lets you change the rules without touching a single flag.

Everyday analogy

Imagine a job advert that says: candidates must have a degree and five years of experience, and must be fluent in either French or German. The advert is the segment. “Degree and five years” is one rule group where all conditions must hold. “French or German” is another where any one is enough. A candidate qualifies only when every rule group is satisfied. Flagsmith segments work in the same layered way.

Segments are shared, overrides are local

A segment is defined at the project level, so the same definition is available in every environment. The override, which says what members receive for a particular flag, is stored per environment. This means “internal staff” can mean the same thing in Development, Staging and Production, while the flag’s behaviour for them can differ in each. Understanding this split avoids many surprises when moving settings between environments.

i
Note

Flagsmith can also create segments that are specific to a single feature. Such a segment is built from the flag’s override screen and belongs only to that flag. It is convenient for a one-off audience, but a shared, named segment is better when the same group will be reused.

3How Traits Reach Flagsmith

Rules can only judge what they can see. Before writing a single condition, you must know where the facts come from.

No identity, no segment

Segments work on identities. When your application asks Flagsmith for flags without saying who the user is, Flagsmith can only return the environment’s default values. It has nobody to test against. To use segments, your application must identify the user, passing a unique identifier, and usually a set of traits at the same time. Only then can the rules be evaluated for that person. This is the most common reason that a segment seems to “do nothing” during a first trial.

Where traits come from

Traits are supplied by your own application, since only it knows the facts. A web shop might send the customer’s plan, signup date, country and number of past orders. A mobile app might add the app version, the operating system and the device type. Traits can be sent each time the user is identified, and Flagsmith can also store them so they are remembered between visits. The choice between sending and storing depends on how your systems are arranged and which version of Flagsmith you use.

1

Your app knows a fact

For example, the logged-in customer is on the premium plan and lives in India.

2

The app identifies the user

It sends the user’s identifier to Flagsmith and includes the relevant traits in the same request.

3

Flagsmith checks the segments

Every segment override on the requested flags is tested against the identity and its traits.

4

Flagsmith returns the answers

The application receives the flag values that apply to this particular person.

Types of traits

A trait has a value, and a value has a type. Text such as a country code is a string. A whole number such as the count of past orders is an integer. A decimal number such as a lifetime spend is a float. A true or false fact such as “has verified email” is a boolean. Flagsmith keeps the type with the trait and compares accordingly. The same characters can mean different things: the text “10” and the number ten behave differently when ordered. Sending numbers as numbers, not as text, is therefore important for greater-than and less-than conditions.

TypeExampleTypical useCare needed
Stringcountry = INPlans, regions, rolesSpelling and letter case must match exactly
Integerorders = 12Counts and levelsSend as a number, not as text
Floatspend = 149.50Money and measurementsBe careful with rounding
Booleanverified = trueYes and no factsAgree on true and false, not “yes” and “1”
Everyday analogy

Think of the registration form at a conference. Each box on the form is a trait: name, company, job role, dietary needs. The organiser’s rules, such as “give the vegetarian lunch to anyone who ticked vegetarian”, can only work on boxes that were actually on the form, filled in the expected way. If half the attendees wrote “veggie” and the other half wrote “vegetarian”, the rule misses half of them.

Storing and sending traits wisely

Do

Use one naming style

Pick plan, not Plan in one app and user_plan in another. Trait names are matched exactly.

Do

Send only what rules need

Every trait is data you must protect and pay to move. Send the facts your segments use and nothing more.

Do

Keep values predictable

Use fixed vocabulary such as free, pro and enterprise, not free text typed by users.

Avoid

Sensitive personal data

Do not use traits for passwords, health details or other private information. Chapter 20 explains why.

!
Watch out

Traits sent from a browser or phone app can be changed by a determined user. Never use a client-supplied trait alone to protect something valuable, such as access to paid content. For anything that must be secure, let your own server decide and send the trusted result.

4The Anatomy of a Rule and a Condition

Every segment, however complicated it looks, is built from one small repeating shape.

What is a condition?

A condition is a single yes-or-no test about an identity. It has three parts. The property says which fact to look at, usually the name of a trait. The operator says how to compare it. The value says what to compare it with. Together they read like a short sentence: “country equals IN”, “orders is greater than 5” or “email contains example.com”. When Flagsmith evaluates the condition for a user, the answer is either true or false.

What is a rule?

A rule is a container for conditions. It decides how their separate answers combine into one answer. Flagsmith offers three kinds of rule type. An “all” rule is true only when every condition inside it is true, which behaves like the word AND. An “any” rule is true when at least one condition inside it is true, which behaves like the word OR. A “none” rule is true only when no condition inside it is true, which behaves like “NOT any of these”.

Rule typeBehaves likeTrue whenPlain example
AllANDEvery condition inside is truePremium plan and country is India
AnyORAt least one condition is truePlatform is iOS or platform is Android
NoneNOT ANYNo condition inside is trueNot a test account and not a staff account

How rule groups combine

A segment can hold several top-level rules. They combine like the word AND: the user belongs to the segment only when every top-level rule is true. Inside a rule, conditions combine according to the rule’s type. Rules can also be nested, so that a rule contains other rules. Nesting is what lets you express statements such as “on the paid plan, and either in India or in a country with a local partner, and not a test account”.

flowchart LR
    U["User with traits"] --> T1{"Rule 1 ALL: plan is pro and orders over 3"}
    T1 -- "false" --> OUT1["Not in segment"]
    T1 -- "true" --> T2{"Rule 2 ANY: country is IN or country is NP"}
    T2 -- "false" --> OUT1
    T2 -- "true" --> T3{"Rule 3 NONE: is_test is true or is_staff is true"}
    T3 -- "false" --> OUT1
    T3 -- "true" --> IN1["In the segment"]
FIG 2 · Top-level rules combine like AND: failing any one of them removes the user from the segment

The figure follows one user through three top-level rules. First, the user must be on the pro plan and have placed more than three orders. If either is false, the journey ends and the user is outside the segment. Second, the user must be in India or Nepal, where only one of the two conditions is needed. Third, the user must not be a test account or a staff account, which is what a “none” rule checks. Only a user who passes every checkpoint reaches the segment. Reading the rules as a series of gates is a reliable way to predict the result.

Everyday analogy

Airport security has several gates in a row. A passenger needs a valid ticket and a passport at the first gate. At the second gate, any one approved form of ID will do. At the third gate, nothing on a prohibited list may be found in the bag. Pass all three and you board. A segment’s top-level rules are those gates, and each gate has its own style of checking.

i
Tip

Before building a segment in the dashboard, write it as a plain sentence on paper. Mark every “and”, “or” and “not”. Each “or” tells you where an “any” rule belongs, and each “not” tells you where a “none” rule belongs. This prevents most logic mistakes.

5Comparison Operators: Equals, Not Equals and Ordering

The first family of operators asks whether a trait matches, differs from or ranks above or below a value.

Equals and not equals

“Equals” is the simplest condition: it is true when the trait’s value is the same as the one you typed. It suits fixed vocabularies such as plan names, country codes and roles. “Not equals” is its opposite, true when the trait’s value differs from the one you typed. Both are strict. A trait of “Premium” does not equal “premium” if the system treats letter case as significant, which is common, so agree on one style and check how your version behaves.

Greater than and less than

The ordering operators compare numbers. “Greater than” is true when the trait is above the value, and “less than” when it is below. Flagsmith also offers inclusive forms, “greater than or equal” and “less than or equal”, which are true when the trait equals the value as well. The difference matters at the edge. A rule that says “orders greater than 5” excludes someone with exactly five orders, while “greater than or equal to 5” includes them.

OperatorPlain meaningExample conditionMatches when trait is
EqualsExactly the sameplan equals propro
Not equalsAnything elseplan not equals freepro, enterprise, or any other set value
Greater thanStrictly aboveorders greater than 56, 7, 8 and so on
Greater than or equalAt or aboveorders at least 55, 6, 7 and so on
Less thanStrictly belowage less than 1817, 16, 15 and so on
Less than or equalAt or belowage at most 1818, 17, 16 and so on
Everyday analogy

A roller coaster has a sign: riders must be at least 120 centimetres tall. “At least” includes the child who is exactly 120. If the sign said “taller than 120”, that same child would be turned away. The words are close, the outcomes differ, and both are easy to confuse when written quickly. Operators in Flagsmith are the same: the boundary value is where mistakes hide.

Semantic versions

App versions such as 4.2.0 and 4.10.0 are not ordinary numbers or ordinary text. As text, “4.10.0” sorts before “4.2.0” because the character “1” comes before “2”. As a decimal number, it is not even a valid number. Flagsmith therefore supports comparing semantic versions, where each dot-separated part is compared as a number in turn. When you want to say “app version at least 4.2.0”, the condition value must be marked as a semantic version, which the dashboard offers as an option in recent versions. Check your documentation for the exact way it is marked in your version, and always test with versions on both sides of the boundary.

Real-world example: hiding features from old app versions

Mobile companies such as Spotify and Uber, which have publicly described shipping features across many app versions at once, face the problem that an old installed app cannot display a new screen. Targeting on app version lets the server withhold the feature from old versions and offer it only to those able to show it. The segment rule is short, but the harm of getting it wrong, an unusable screen, is large.

!
Watch out

Never compare version numbers as plain text. A rule that says “version greater than 4.2” in text terms treats 4.10 as lower than 4.2. Always use the version-aware comparison, and test with a ten, a nine and a single-digit version to prove it works.

6Text and Presence Operators

The second family of operators looks inside text, checks lists, and asks whether a trait exists at all.

Contains and does not contain

“Contains” is true when the trait’s text includes the given piece anywhere inside it. A segment for a partner company’s staff might say “email contains partner.example.com”. “Does not contain” is the reverse. These operators are flexible, but they are also easy to over-match. The text “pro” is contained in “professional” and in “improve”, so a short fragment can capture people you never intended. Prefer longer, more distinctive fragments, or use an exact equals when the vocabulary is fixed.

The “in” operator

“In” checks whether the trait’s value is one of a list of values, separated by commas. It is shorter and clearer than a long “any” rule full of separate equals conditions. For example, “country in IN, NP, BD” means the country is India, Nepal or Bangladesh. Because it matches whole values, not fragments, it avoids the over-matching trouble of “contains”.

Is set and is not set

Sometimes the question is not what a trait is, but whether you know it at all. “Is set” is true when the identity has a value for the trait. “Is not set” is true when it does not. These are the correct way to handle missing information. For example, you might give a feature to everyone for whom a “preferred_language” is not set, using a default. Do not try to test emptiness with a not-equals condition, because the way missing traits are treated in other operators may surprise you, as later chapters explain.

Regular expressions

A regular expression, often shortened to regex, is a compact pattern language for describing text. It can express things that “contains” cannot, such as “starts with a letter followed by exactly four digits” or “ends with either .edu or .ac.uk”. Flagsmith’s regex operator is true when the trait’s text matches the pattern you supply. Regex is powerful, and it is also the easiest operator to get subtly wrong. Patterns that look right can match more or less than you expect, and the exact flavour of pattern language depends on the engine evaluating it, so keep them short and test them on many sample values.

OperatorPlain meaningExampleBest used for
ContainsText includes this pieceemail contains partner.example.comDomains and tags
Not containsText lacks this pieceemail not contains testExcluding obvious test accounts
InValue is on this listcountry in IN, NP, BDShort fixed lists
Is setThe trait existscompany is setDetecting known data
Is not setThe trait is missingcompany is not setHandling unknown data
RegexText fits a patternuser code fits a patternStructured identifiers
Everyday analogy

Searching a library is similar. “Contains” is like searching for any book with the word “river” anywhere in the title, which finds rivers, riverboats and Riverdale. “In” is like asking for a specific list of titles. “Is set” is like asking whether the book has an author on its record at all. A regular expression is like a librarian’s advanced search form, powerful but needing careful instructions.

!
Watch out

Over-matching is the classic text mistake. A condition such as “email contains admin” will also match “radmin” and “administrator-fan@example.com”. When a wrong match could expose a feature to the wrong people, prefer exact operators and complete values.

i
Tip

For any regex condition, keep a short list of three values that must match and three that must not. Test all six after every edit to the pattern. Six quick checks catch most pattern mistakes.

7Special Operators and Built-in Properties

Some conditions do not look at a trait you sent. They look at the identity itself, at the environment, or at a number made from the identity.

Percentage split

The percentage split operator is true for a chosen share of users, such as ten percent. It does not look at any trait. Instead, Flagsmith turns the user’s identifier, mixed with something unique to the segment, into a number between zero and one hundred, and the condition is true when that number falls under your chosen percentage. Because the calculation is repeatable, the same user always lands on the same side. Chapter 10 explains why this stability is so valuable.

Modulo

The modulo operator divides a numeric trait by a number you choose and checks the remainder. It is useful for splitting people into repeating groups by a number they already have, such as a customer number. If you divide by two and look for a remainder of zero, you select every even number. If you divide by ten and look for a remainder of three, you select one tenth of customers, those whose number ends in three. It is an old, dependable trick for creating stable test groups from numeric identifiers, though the percentage split is usually easier.

Built-in properties

Besides traits you send, Flagsmith can expose a few built-in properties to rules. In recent versions, these include the identity’s own identifier and the name of the environment being asked about. A rule on the identifier lets you target a known list of users without inventing a trait for them. A rule on the environment name lets one segment behave differently in Staging and Production, though this should be used sparingly, because it hides environment differences inside the rule itself. Check your version’s documentation for the exact names of these properties and whether they are available to you.

Operator or propertyWhat it looks atTypical useCaution
Percentage splitA repeatable number made from the identityGradual rolloutsSame user always in the same position
ModuloRemainder of a numeric traitStable test groupsNeeds a numeric trait
Identity identifierThe user’s unique IDTargeting a named listLists grow stale quickly
Environment nameWhich environment is askingRare special casesHides differences inside the rule
Everyday analogy

A teacher who wants to split a class into groups does not ask each pupil to describe themselves. She uses something already on the register, such as the roll number: even numbers form one group, odd numbers the other. The split needs no questions, and it is the same every day. A percentage split and a modulo condition are digital versions of the register trick.

i
Tip

If you want to give a feature to a small, named list of people, such as your testers, a segment based on identity identifier works. If the list will grow past a dozen or so people, create a trait such as tester instead and send it from your own system, where the list is already maintained.

8Combining Conditions: AND, OR and NOT Without Mistakes

Individual conditions are easy. The errors creep in when you combine them, so a little logic goes a long way.

The three connectors

Every audience description is built from three connecting ideas. AND narrows the audience, because a person must satisfy both sides. OR widens the audience, because a person need satisfy only one side. NOT flips an answer, turning a match into a non-match and the reverse. In Flagsmith, AND and OR are expressed by the “all” and “any” rule types, while NOT is expressed by the “none” rule type, and by operators with a negative meaning such as “not equals”.

AND

Narrows

“Premium and in India” is smaller than either “premium” or “in India” alone. Each added AND shrinks the group.

OR

Widens

“iOS or Android” is larger than either alone. Each added OR enlarges the group.

NOT

Flips

“Not a test account” includes everyone except the test accounts. The size depends on how many are excluded.

The two classic traps

The first trap is mixing up the meaning of “none” with “not all”. A “none” rule is true only when every condition inside it is false. If you write “none of: is_test is true, is_staff is true”, then a person who is staff is excluded even though they are not a test account. People who intended to exclude only those who are both test and staff have written the wrong rule. Say aloud what you mean: “exclude anyone who is a test account, and also exclude anyone who is staff” is a “none” rule, while “exclude people who are both” needs a different structure.

The second trap is a negative that does not behave as hoped. Suppose you want everyone who is not on the free plan. A “plan not equals free” condition seems perfect, but if some users have no plan trait at all, the way the missing value is handled may leave them out. The safer wording is often a positive list, such as “plan in pro, team, enterprise”, because it says exactly who should be included instead of describing everyone else.

Everyday analogy

A restaurant sign says “No shirts, no shoes, no service”. A customer wearing a shirt but no shoes is refused. The word “no” applies to each item separately, so being missing either one is enough to fail. People often read it as “no shirt and shoes together”, which is a different rule altogether. Segment logic has the same pitfall in plain language: the words feel obvious until two readers disagree on what they meant.

A reliable method

1

Write the audience as one sentence

For example: “Pro customers in India or Nepal who are not test accounts.”

2

Mark every connector

Circle each and, or and not. Here: and between plan and country, or between the two countries, and not for the test accounts.

3

Give each group its own rule

One “all” rule for the plan, one “any” rule for the two countries and one “none” rule for the test flag.

4

Prefer positive wording

Where possible, say who is in, not who is out, to avoid problems with missing data.

5

Test the edges

Try people who satisfy all but one condition. A correct segment rejects each of them for exactly the right reason.

!
Watch out

An “any” rule with a single condition inside it behaves exactly like that condition. An “any” rule with no useful conditions can behave in surprising ways. Do not leave empty or half-built rules in a saved segment, and review the final rule list after every edit.

9Six Worked Examples

Reading about operators is useful. Seeing complete segments for realistic needs is better.

Each example below describes an audience in words, then shows how its rules are put together. They are built for an imaginary online shop called BrightCart, which sends traits named plan, country, orders, app_version, platform, email and is_test.

Example 1: Internal staff

Goal: Show new features to employees first. Rules: One “any” rule with a single condition, email contains the company’s own mail domain. Why it works: staff always use company email addresses. Improve it: a trait such as is_staff sent from your own user database is safer than a text match, because it cannot be faked by someone typing a similar-looking address.

Example 2: Premium customers in selected countries

Goal: Roll out a feature where you have licences. Rules: Rule 1 is an “all” rule with plan equals premium. Rule 2 is an “any” rule with country in IN, NP, BD. Why it works: two top-level rules combine like AND, so a user needs both. Watch: make sure country codes are sent in one consistent style, such as two capital letters.

Example 3: Mobile users on a recent app

Goal: Offer a screen only to apps that can display it. Rules: Rule 1 is an “any” rule with platform in ios, android. Rule 2 is an “all” rule with app_version at least 4.2.0, marked as a version comparison. Why it works: the version check uses semantic ordering, so 4.10.0 correctly beats 4.2.0.

Example 4: Loyal customers

Goal: Reward people who buy often. Rules: One “all” rule with orders at least 10 and plan not equals free. Why it works: both parts must be true. Watch: if some accounts have no plan trait, use a positive list of paid plans.

Example 5: A ten percent trial group, excluding test accounts

Goal: Try a feature on a small, random slice of real customers. Rules: Rule 1 is an “all” rule with a percentage split of ten. Rule 2 is a “none” rule with is_test equals true. Why it works: the split picks a stable ten percent, and the “none” rule removes test accounts. Improve it: keep this segment generic, and raise the percentage over time as confidence grows.

Example 6: Everyone except a small blocked group

Goal: Give a feature to all customers, but withhold it from a handful of accounts under review. Rules: One “none” rule with account_status equals under_review. Why it works: the segment includes everybody not in the blocked state. Watch: users with no account_status trait should be tested explicitly, to confirm they behave as intended.

ExampleRule types usedOperators usedMain risk
Internal staffAnyContainsLook-alike addresses
Premium in selected countriesAll and anyEquals and inInconsistent country codes
Recent mobile appsAny and allIn and version comparisonComparing versions as text
Loyal customersAllAt least and not equalsMissing plan values
Ten percent trialAll and nonePercentage split and equalsForgetting to exclude test accounts
Everyone except blockedNoneEqualsMissing status values
i
Tip

Save a short description with every segment explaining who it is for, who asked for it and which traits it needs. When a trait changes in the application, you will know at once which segments to check.

10Percentage Splits in Depth

A percentage rollout looks trivial, but a surprising amount of good engineering sits behind the phrase “ten percent of users”.

Why not simply flip a coin?

Imagine deciding on every page load, with a random number, whether to show the feature to ten percent of people. A single visitor would see the new design on one page, the old design on the next and the new design again after a refresh. The experience would flicker, bug reports would be impossible to reproduce and any measurement of the feature’s effect would be meaningless. What you want is for each person to be assigned once, and to stay assigned.

How stable assignment works

Flagsmith takes the user’s identifier, mixes it with something specific to the segment, and passes the result through a mathematical scrambling function called a hash. The output looks random but is completely repeatable: the same input always produces the same number. That number, scaled to the range zero to one hundred, is compared with your chosen percentage. Because the same person always produces the same number, they always get the same answer, on every device, as long as their identifier does not change.

Everyday analogy

Think of a school sorting pupils into four colour houses by the first letter of their birth month. The result looks arbitrary, yet each pupil is always in the same house, every day and in every class, and nobody has to remember anything. A hash is a far better scrambler than a birth month, but the idea is the same: a repeatable rule that spreads people evenly.

Widening a rollout keeps early users

Because assignment depends only on the user’s position in the scrambled order, raising the percentage from ten to twenty-five keeps everyone who was already in and adds more. Nobody who had the feature loses it as you widen. This is why you can start small and expand with confidence, knowing that early users keep a consistent experience.

10%
first cautious slice of real customers
25%
enough users to see patterns in the numbers
100%
everyone, after which the rule can be retired

Different segments pick different people

Since the calculation mixes in something unique to each segment, two segments with the same ten percent do not select the same ten percent of users. This is useful. Two unrelated experiments will not accidentally land on exactly the same unlucky group. If you need two features to reach exactly the same people, build one segment and use it on both flags.

Common mistakes with percentages

Mistake

Changing the identifier

If your app uses an anonymous ID before login and a different ID after login, the same human may switch sides. Use one stable ID.

Mistake

Expecting exact numbers

Ten percent is a statistical target. Over a small number of users, the actual share can drift noticeably above or below it.

Mistake

Rebuilding the segment

Deleting a segment and creating a new one with the same name produces a new scramble, reshuffling everyone.

Mistake

Mixing in other rules carelessly

Combining a split with other conditions means the percentage applies only to people who meet the other conditions.

Real-world example: Google and live experiments

Google has described in public research how it exposes changes to small, consistently assigned slices of traffic before wider release, measuring effects as it goes. Stable assignment, so that the same user stays in the same group, is what makes such measurements trustworthy.

i
Tip

Agree on a single, permanent identifier for each user across web, mobile and backend services. A stable identity is the foundation of every percentage split.

11Segment Overrides and the Order of Precedence

A segment on its own changes nothing. It becomes meaningful when a flag uses it, and when several segments compete, order decides the winner.

What is a segment override?

A segment override is an instruction attached to a flag, in one environment, saying “for members of this segment, behave like this”. The override can set its own enabled position and, for remote configuration flags, its own value. Members of the segment receive the override’s answer. Everyone else keeps receiving the flag’s default answer for the environment.

When a user belongs to several segments

One person can match many segments at once: a premium customer, in India, on iOS, in the staff group. If the flag has overrides for several of those segments, Flagsmith needs a tie-breaker. It uses the order of the override list. The segments are checked from the top, and the first one the user belongs to supplies the answer. Segments lower down are ignored for that flag. You control the order by dragging overrides up and down in the flag’s screen.

flowchart TD
    A["Flag requested for an identity"] --> B{"Identity override exists?"}
    B -- "Yes" --> R1["Use the identity override"]
    B -- "No" --> C{"In first segment override?"}
    C -- "Yes" --> R2["Use the first matching segment override"]
    C -- "No" --> D{"In next segment override?"}
    D -- "Yes" --> R3["Use that override"]
    D -- "No" --> E["Use the environment default value"]
FIG 3 · How one flag’s answer is chosen: identity override first, then segments in priority order, then the default

Follow the arrows from the top. When a flag is requested for an identity, Flagsmith first checks whether that specific person has a personal override. If they do, that is the answer, and nothing else is considered. Otherwise it walks down the list of segment overrides in priority order and stops at the first segment the person belongs to. If the person matches none, the environment’s default value is returned. The figure shows only two segment steps, but the list can be longer.

Everyday analogy

A hotel decides which welcome gift to place in a room. The first rule on the list is “personal request noted in the booking”, which beats everything. Next is “loyalty member”, then “booked through partner site”, then “ordinary guest”. A guest who is both a loyalty member and a partner booking gets the loyalty gift, because that rule comes first. If the hotel swapped the order of the two rules, that same guest would get the partner gift.

Ordering advice

1

Narrow and special first

Put small, deliberate audiences such as staff and testers at the top, so that their experience is never overridden by broader groups.

2

Percentage rollouts in the middle

Gradual audiences sit below the narrow ones and above the very broad catch-all groups.

3

Broad groups last

Wide segments such as “all paying customers” go near the bottom, where they only affect people who matched nothing narrower.

4

Explicit exclusions near the top

If a group must never see the feature, an override turning it off for that group should come before the audiences that turn it on.

Real-world example: staff first, then the world

GitHub engineers have publicly described releasing changes to employees before the general public. In override terms, that is a staff segment at the top of the priority list with the feature on, followed by wider percentage segments below it. The order of the list is part of the release plan, not an afterthought.

!
Watch out

Reordering overrides can change what real users see the moment you save. Treat a priority change in Production with the same care as turning a flag on, and record why it was made.

12The Evaluation Journey from Request to Answer

Watching one request travel from your application to Flagsmith and back makes every earlier chapter click into place.

sequenceDiagram
    participant APP as Application
    participant SDK as Flagsmith SDK
    participant FS as Flagsmith
    participant ENG as Rule Engine
    APP->>SDK: Identify user with traits
    SDK->>FS: Request flags for this identity
    FS->>ENG: Evaluate segments for the identity
    ENG->>ENG: Check each rule group and condition
    ENG-->>FS: Return matching segments
    FS->>FS: Apply identity and segment overrides in order
    FS-->>SDK: Return flag values for this user
    SDK-->>APP: Flags ready to use
FIG 4 · One user’s request: traits go in, matching segments are found, overrides are applied, answers come out

The application starts by telling the SDK who the user is and what is known about them. The SDK sends this to Flagsmith, asking for the flags that apply. Flagsmith hands the identity and traits to its rule engine, which walks through every segment relevant to the requested flags, checking each rule group and each condition. The engine reports which segments the user belongs to. Flagsmith then applies the overrides in priority order, as Chapter 11 described, and returns the final flag values. The SDK passes them to the application. This whole journey usually takes a fraction of a second.

Evaluation on your own server

For high-traffic backends, Flagsmith’s server-side SDKs offer a local evaluation mode. Instead of asking Flagsmith each time, the SDK downloads the environment’s complete rule set, including segments and overrides, and runs the same rule engine inside your own service. Answers become extremely fast, and the application continues to work if the network to Flagsmith is briefly interrupted. The trade-off is a short delay before rule changes reach your servers, as the SDK refreshes on a timer. Check your SDK documentation for the refresh interval and any differences in supported features.

Everyday analogy

Calling a help desk each time you need an answer is like the direct request: always current, but the line can get busy. Keeping a printed copy of the rulebook at your own desk is like local evaluation: instant and robust, but you must replace the printout now and then. Both give the same answers for the same rules. They differ in when you learn that a rule has changed.

What the engine needs from you

Input

A stable identifier

The unique key for the user, used for personal overrides and percentage splits.

Input

Correct traits

Names spelled exactly as the rules expect, with values of the right type.

Input

The right environment key

Segments are shared across the project, but overrides are read from the environment your key belongs to.

Input

Fresh enough rules

With local evaluation, rules are as recent as the last refresh, so allow for that delay when testing.

i
Tip

When something looks wrong, ask three questions in order. What identifier was sent? Which traits came with it? Which environment key was used? More than half of all “the segment is broken” reports end at one of these three answers.

13Edge Cases: Missing, Mismatched and Messy Data

Real data is never as tidy as examples. These are the situations that produce the strangest segment behaviour.

The trait that is not there

Not every user has every trait. A brand-new visitor may have no plan, no country and no order history. For most operators, a condition on a missing trait simply does not match, because there is nothing to compare. This is usually what you want. The surprising cases come from negative operators. A condition such as “plan not equals free” might not match a user with no plan at all, since there is no value to be different from. Behaviour in edge cases can differ between versions and operators, so always test missing traits explicitly instead of assuming.

Wrong type, wrong result

If a number is sent as text, an ordering condition may not behave as expected. The text “9” is considered greater than the text “10” in dictionary order, because “9” comes after “1”. Sending the count of orders as a real number avoids the problem. Similarly, sending the word “true” as text where a true-or-false value was expected can lead to a condition silently failing to match. Agree on types in your application, and keep them consistent across web, mobile and backend code.

Capital letters, spaces and spelling

Strings usually need to match exactly, including letter case and any hidden spaces at the start or end. A plan sent as “Pro ” with a trailing space is not the same as “Pro”, and neither is “pro”. These mistakes are invisible on the screen and very frustrating to find. Clean values in your application before sending them, preferably to a lowercase, trimmed form, and document the permitted vocabulary.

SituationLikely resultSafer practice
Trait missing, positive operatorCondition does not matchExpected, but test it once
Trait missing, negative operatorBehaviour may surprise youUse a positive list or “is not set”
Number sent as textOrdering compares as textSend real numbers
Different letter caseMay not matchNormalise values before sending
Trailing or leading spacesDoes not matchTrim values before sending
Anonymous user, no identitySegments are not evaluatedIdentify the user, or accept defaults
Identifier changes at loginUser may jump between segmentsUse one stable ID
Everyday analogy

An airport check-in desk can only verify the details on the passport. A passenger who gives the name “Jon” when the ticket says “Jonathan” is turned away by the computer, even though a human would see they are the same person. Rules are as strict as that computer, and they give a clear answer only when the data arrives clean.

Real-world example: the tidy-data habit

Large online companies such as Amazon and Netflix have long emphasised that decisions at scale depend on consistent, well-defined data. A feature flag system inherits that principle: the audience rule is exactly as reliable as the information fed to it. Teams that agree on a small shared vocabulary of traits avoid most of the strange behaviour described above.

!
Watch out

A rule that looks perfect in the dashboard can still fail in production if the application sends the trait under a slightly different name. Compare the exact trait names in your code with the exact names in your conditions whenever a segment seems to match nobody.

14Testing Segments Before Real Users Depend on Them

A segment is a small program written in clicks. Like any program, it deserves tests, and the tests are cheap.

Why test at all?

A wrong segment is a quiet failure. Nothing crashes. A feature simply reaches too many people, too few people or the wrong people, and the mistake can stay hidden for weeks. The cost is not a technical error message but a confused customer, a leaked feature or an experiment whose results cannot be trusted. A few minutes of deliberate testing before a segment goes live is the best value in the whole process.

The test identity matrix

The most reliable technique is to create a small set of test identities, each designed to prove one thing. For every segment, include at least one person who should be inside, and several who should be outside for different reasons: one failing each condition, one with a missing trait and one sitting exactly on a boundary value. Then check, for each of them, what the flag returns.

Test identityTraitsExpected resultWhat it proves
Typical memberplan pro, country IN, orders 12In the segmentThe main path works
Wrong planplan free, country IN, orders 12OutsideThe plan condition is enforced
Wrong countryplan pro, country US, orders 12OutsideThe country condition is enforced
On the boundaryplan pro, country IN, orders 5Depends on the operator“Greater than” versus “at least”
Missing traitplan pro, no countryOutsideMissing data is handled
Wrong caseplan Pro, country INPer your ruleLetter case behaviour
Excluded groupplan pro, country IN, is_test trueOutsideThe exclusion rule works
Everyday analogy

A lock-maker testing a new lock does not only check that the right key opens it. She also tries a key that is slightly too short, one that is slightly too long, one with a worn tooth and one from another lock. A lock that opens for the right key but also opens for the wrong ones is worse than useless. Testing segments is the same: the wrong visitors matter as much as the right ones.

Using the dashboard to help

Flagsmith’s dashboard can show which stored identities currently match a segment, when traits are saved against identities. This is a helpful sanity check: the list should look like the audience you meant. It cannot replace tests that include missing and edge-case data, because those identities may not exist yet. You can also create identities by hand in a non-production environment, give them chosen traits and see the flag values they would receive.

Automated checks

1

Keep test identities permanent

Give them clear names and keep them in your test environment, so every future edit can be checked against the same people.

2

Write a small script or test suite

For each test identity, ask the flag service for the flags and compare them with the expected values. A failing check names the segment that drifted.

3

Run it before and after each change

Run the checks before editing a segment to prove they pass, and again afterwards to prove nothing else broke.

4

Run it after promotion

After any Production change, run a smaller version of the same checks against Production test identities.

i
Tip

Keep test accounts out of real analytics and out of percentage splits. A trait such as is_test, combined with a “none” rule in your production segments, stops internal testing from polluting your numbers.

15Segments Across Environments

Segments are shared across a project, but their effects are decided separately in each environment. This split is the source of many puzzling moments.

Define once, override separately

When you create a segment, it exists for the whole project. The same name and the same rules are available in Development, Staging and Production. What differs is whether a given flag has an override for the segment in each environment, and what that override says. A flag might give the staff segment the new behaviour in Staging, but have no override for it yet in Production.

One edit, many environments

Because the rules are shared, editing a segment changes it everywhere at once. Add a condition in Development while experimenting, and the same condition is now in force in Production, for every flag that uses the segment. This is convenient and dangerous in equal measure. Experiments with new rules belong in a copy of the segment, or in a feature-specific segment, until you are sure. Never use the shared, production-facing version as a scratchpad.

flowchart LR
    SEG["Segment: Premium India, defined once"] --> DEV["Development: override on, value practice"]
    SEG --> STG["Staging: override on, value practice"]
    SEG --> PRD["Production: override on at 10 percent, value live"]
FIG 5 · One segment definition, three separate sets of overrides, one per environment

The figure shows a single segment feeding three environments. The audience definition is identical in all three, because it comes from the one segment. The consequences differ: Production uses the real value and a small percentage, while the lower environments use practice values. When you promote a flag from Staging to Production, you recreate the override in Production, but you do not need to recreate the segment.

Everyday analogy

A company-wide definition of “senior employee”, say more than ten years’ service, is written once by the head office. Each branch then decides what seniors receive: one branch gives extra holiday, another a parking space. If head office changes the definition to eight years, every branch’s seniors change at once, even though each branch still decides its own benefit. Segments behave this way.

Safe habits

Habit

Treat segment edits as Production edits

Because the change is shared, give it the same review as a Production flag change.

Habit

Duplicate before experimenting

Copy the segment, work on the copy and swap it in only when proven.

Habit

Check where it is used

Before editing, look at which flags use the segment, so you know the reach of the change.

Habit

Keep identities separate

Traits sent from a Staging app should describe test users, so they never confuse Production rules.

Real-world example: shared definitions, local decisions

Large organisations such as Etsy have publicly described separating shared definitions of audiences from the individual features that use them, so product teams can reuse well-understood groups. The benefit is the same one a shared segment provides: one place to define a group, many places to use it.

!
Watch out

If your project uses change approvals, remember that editing a shared segment may not pass through the same approval flow as a flag change in your version. Confirm how your plan treats segment edits, and add a team habit of review where the tool does not.

16Segment Design Patterns

Most useful segments fall into a handful of familiar shapes. Recognising them speeds up design and makes segments easier for others to read.

Pattern

Internal staff

Gives employees early access. Usually built from a trusted trait, and placed at the top of priority lists.

Pattern

Beta programme

A named group who opted in. Built from a trait that records consent, so it is both fair and traceable.

Pattern

Plan or entitlement

Groups customers by the plan they pay for. Long-lived, tied to product and pricing decisions.

Pattern

Geography

Targets countries or regions for legal, language or partner reasons. Needs a consistent code vocabulary.

Pattern

Platform and version

Matches operating system or app version, so that features reach only apps able to show them.

Pattern

Cohort by date

Groups users by when they joined, such as everyone who signed up this quarter, for fair experiments.

Pattern

Gradual rollout

A percentage split with exclusions, widened step by step over days or weeks.

Pattern

Safety exclusion

A group deliberately kept out, such as accounts under review or customers in a regulated state.

Naming that explains itself

Names are the cheapest documentation a segment has. Describe the group in business words, not in rule-language. “Premium customers in India” reads well in an override list. “plan eq premium and country eq IN” explains how the group is built, which anyone can see by opening it, but not why it exists. Keep a single style, and avoid dates, people’s names and temporary words such as “new” or “test2” which are meaningless a month later.

Weak nameBetter nameWhy better
segment1internal-staffSays who is in the group
johns-test-groupbeta-checkout-testersNames the purpose, not a person
oct-promo-userspromo-eligible-customersDoes not expire with the calendar
india-premium-ios-newpremium-indiaShort, with other conditions inside the rules

Small, composable segments

A common design question is whether to build one large segment with many conditions or several small segments. Small segments are easier to understand and reuse. Large ones are easier to read in one place but harder to change safely. A good habit is to keep each segment to one clear idea, such as “premium customers”, and to combine ideas at the flag level through ordered overrides rather than stuffing every possible combination into a single segment.

Everyday analogy

A kitchen with many small, well-labelled containers is easier to cook in than one giant jar of mixed spices. You can combine exactly what you need, and replacing one container does not spoil the others. Segments built around one idea work the same way: reusable, clear and easy to swap.

i
Tip

For every segment, write a one-line description naming its owner and purpose. When the owner leaves the team, a quick search for orphaned segments tells you exactly where cleanup is needed.

17Anti-patterns to Avoid

An anti-pattern is a habit that looks reasonable and causes trouble later. These five are the most common in targeting rules.

ANTI-PATTERN 01 · THE MEGA-SEGMENTAvoid
What it looks like

One enormous segment with a dozen rule groups, built to cover every audience a product team might ever want.

Why it hurts

Nobody can read it, nobody dares edit it and one change can reshape the audience of many unrelated flags.

Do this instead

Create several small segments, each with one clear idea, and combine them with ordered overrides on each flag.

ANTI-PATTERN 02 · SECURITY BY CLIENT TRAITAvoid
What it looks like

A segment that unlocks paid content based on a trait sent by a browser or phone app, such as plan equals premium.

Why it hurts

Anyone able to change the value in their own app can give themselves premium features. Client-side traits can be edited by the person holding the device.

Do this instead

Enforce access on your server using trusted data. Use segments for presentation and rollout, not for protection.

ANTI-PATTERN 03 · THE HIDDEN NEGATIVEAvoid
What it looks like

A segment built entirely from “not equals” or “does not contain” conditions to mean “everyone except these”.

Why it hurts

Users with missing traits may fall outside the segment, so the audience is smaller than intended, and the problem only appears with real data.

Do this instead

Use positive lists where possible, or combine “is set” checks with exclusions, and test with missing values.

ANTI-PATTERN 04 · THE LONG PASTED LISTAvoid
What it looks like

Hundreds of user identifiers pasted into a single condition to give a feature to a named group.

Why it hurts

The list is stale the day after it is written, hard to review, easy to break by a stray comma and slow to evaluate.

Do this instead

Send a trait such as beta_tester from the system where the list is truly maintained, and write one simple condition on it.

ANTI-PATTERN 05 · THE ABANDONED SEGMENTAvoid
What it looks like

Dozens of segments from old experiments, each with an unclear name, none with an owner, some used by no flag at all.

Why it hurts

New team members cannot tell what is safe to change, and rules based on traits that no longer exist silently match nobody.

Do this instead

Give each segment an owner and purpose, and review the list on a regular schedule, removing what is unused.

Real-world example: complexity as a cost

Engineering writers at companies such as Facebook and Google have often warned that conditional behaviour, left unmanaged, becomes one of the hardest parts of a system to reason about. Targeting rules are conditional behaviour about people. Keeping them small, named and owned is the discipline that stops them from becoming a maze.

18Performance and Scale

A single segment check costs almost nothing. Millions of checks, each against dozens of segments, are worth thinking about.

What makes evaluation heavier?

Evaluating a segment means walking its rules and testing each condition against the user’s traits. A segment with three conditions takes negligible time. A segment with fifty conditions, several regular expressions and long lists of values takes longer, and a flag with twenty overrides multiplies that cost. For one request, the total is still tiny. For a busy service handling thousands of requests each second, small costs add up, and the simplest rules are the cheapest.

Cheap

Equals, in, is set

Simple exact comparisons are very fast, even over many requests.

Cheap

Number comparisons

Greater-than and less-than checks on numbers are fast and predictable.

Moderate

Contains

Searches inside text, so cost grows with the length of the text.

Heavier

Regular expressions

Complex patterns can be slow, and badly written ones can be very slow on certain inputs.

Habits that keep targeting fast

1

Send only the traits rules use

Smaller identities travel faster and cost less to store and evaluate.

2

Prefer exact operators

Use equals and in where the vocabulary is fixed. Reserve regular expressions for the few cases that need them.

3

Ask for flags once per request

Read the needed flags at the start of handling and reuse the answers, instead of asking repeatedly inside the same request.

4

Use local evaluation on busy backends

Evaluating inside your own service avoids a network call for every decision.

5

Retire unused overrides

Every override on a flag is a test to run. Removing dead ones makes every request slightly cheaper.

1,000
requests per second on a busy service
3
flags read per request, so 3,000 decisions a second
0
network calls per decision with local evaluation
Everyday analogy

A concert doorkeeper checking a ticket by looking at its colour is fast. One who must read a long paragraph of small print on every ticket slows the whole queue. Simple rules keep the line moving. If the line gets long, switching to a pre-printed guest list, which is what local evaluation provides, is faster than phoning head office about each person.

Real-world example: decisions close to the traffic

Companies that serve enormous traffic, such as Netflix, have publicly described designs where configuration is cached close to where it is used, so that no central service is asked on every request. Local evaluation of segment rules follows the same principle: the decision is made next to the traffic, using a recent copy of the rules.

i
Tip

Before blaming flags for a slow request, measure. In most systems, flag evaluation is a very small share of the total time. Simplify rules when you have evidence, not on suspicion.

19Privacy, Security and Responsible Targeting

Targeting rules are built from information about people. That information deserves care, whatever the size of your company.

Data minimisation

Data minimisation is the principle of collecting and sending only what is needed for a stated purpose. Every trait you send to a flag service is a piece of personal information in another system. If a segment needs to know whether a customer is in the paid tier, send “paid” or “free”, not their billing history. If it needs a rough region, send a country code, not a home address. Smaller, simpler traits reduce risk, speed up evaluation and make privacy reviews easier.

Traits that should not be sent

Never

Passwords and secrets

No credentials, tokens or keys of any kind belong in a trait.

Avoid

Sensitive categories

Health, religion, political views and similar details should not drive feature targeting, and may be restricted by law.

Avoid

Direct contact details

Full email addresses and phone numbers are rarely needed. A domain or a yes-or-no fact usually serves.

Avoid

Free text from users

Text typed by people is unpredictable and may contain anything, including things you did not mean to collect.

Client-side visibility

When an application running on a user’s own device asks for flags, it can see the answers it receives. Flag values and, in some arrangements, the existence of flags are visible to a determined person inspecting the app. For this reason, never place secrets or private business information in remote values, and never rely on a client-side segment to hide something that is truly confidential. Treat everything a client can read as readable by the user.

Everyday analogy

A shop assistant who asks for your full life story before selling you a coat is asking for far too much. A good assistant asks only your size. A rule that needs your size should receive your size and nothing else. The more a system knows, the more there is to protect, and the more there is to lose if something goes wrong.

Fairness and responsibility

Targeting decides who gets what, and some decisions have consequences beyond convenience. Offering a discount only to some groups, or withholding a service from others, can raise fairness and legal questions. Before building segments that affect prices, access or opportunity, ask whether the rule could treat people unfairly, and involve your legal and product colleagues where the stakes are real. A simple technical rule can have a serious human effect.

Good practice

  • Send the smallest trait that serves the rule
  • Use identifiers with no meaning outside your system
  • Review traits and segments on a schedule
  • Record why each sensitive segment exists

Risky practice

  • Sending whole user profiles for convenience
  • Using email addresses as identifiers everywhere
  • Keeping traits long after their purpose ended
  • Targeting prices or access without review
!
Watch out

Laws about personal data differ between countries and change over time. Treat this chapter as general good practice and consult your organisation’s privacy or legal team about the rules that apply to you.

20Debugging: Why Isn’t This User in the Segment?

Sooner or later, someone will ask this question. A calm, ordered method answers it quickly almost every time.

flowchart TD
    A["User reports wrong flag value"] --> B{"Was the user identified?"}
    B -- "No" --> B1["Identify the user and retry"]
    B -- "Yes" --> C{"Correct environment key?"}
    C -- "No" --> C1["Use the key for the right environment"]
    C -- "Yes" --> D{"Traits arrived with right names and types?"}
    D -- "No" --> D1["Fix the trait names or types in the app"]
    D -- "Yes" --> E{"Each condition true for these traits?"}
    E -- "No" --> E1["Correct the condition or the data"]
    E -- "Yes" --> F{"Higher priority override wins?"}
    F -- "Yes" --> F1["Reorder overrides or adjust the winning one"]
    F -- "No" --> G{"Cache or refresh delay?"}
    G -- "Yes" --> G1["Wait one refresh period and retest"]
    G -- "No" --> H["Check identity overrides and audit log"]
FIG 6 · A step-by-step path from a surprising flag value to its cause

The figure moves from the most common causes to the least. First, confirm the user was identified at all, since anonymous requests skip segments. Second, confirm the key belongs to the environment you think you are looking at. Third, check that the traits arrived with the exact names and types the rules expect. Fourth, work through each condition by hand with the actual trait values. Fifth, look for a higher-priority override that is winning. Sixth, allow for caching delay. Finally, look for a personal identity override and read the audit log for recent changes.

Common symptoms and causes

SymptomLikely causeFirst check
Segment matches nobodyTrait name mismatch or missing identificationCompare trait names in code and rules
Segment matches everybodyAn “any” rule with an always-true condition, or a missing ruleRead the saved rules from the top
Some users flicker between valuesUnstable identifierConfirm one ID across login and devices
Staff see the old behaviourA broader override sits above the staff overrideCheck override priority order
Works in Staging, not in ProductionDifferent traits, overrides or keysCompare environment overrides
Recent edit has no effect yetCache or local evaluation refresh delayWait one refresh period and retest
One person always differsAn identity overrideOpen that identity’s overrides
Everyday analogy

A technician fixing a lamp that will not light does not start by replacing the wiring. She checks the plug, the switch, the bulb and the fuse in order, from the simplest and most likely problem to the rarest. The debugging path above follows the same habit: cheap, common checks first, deep investigation last.

i
Tip

Keep one “debug view” in your own tooling that prints the identifier, the traits and the resulting flag values for any user. Being able to see what Flagsmith actually received, not what you believe it received, resolves most questions in minutes.

21Governance and the Segment Lifecycle

Segments are easy to create and easy to forget. A light set of habits keeps the list useful as the product grows.

What is governance?

Governance is simply a set of agreed rules about who may do what, and a way of checking that the rules are followed. For segments, it answers practical questions. Who may create a segment? Who may change one that other people depend on? How do we find segments nobody uses any more? Who decides when a segment is retired? A small team can answer these in a shared document. A large organisation may use roles, reviews and regular audits.

The life of a segment

1

Proposed

Someone describes the audience in words, names the owner and lists the traits the rules will need.

2

Built and tested

Rules are created and checked against the test identity matrix before any flag depends on them.

3

In use

Flags attach overrides to it. Changes are reviewed because they reach every flag that uses the segment.

4

Reviewed

On a regular schedule the owner confirms the segment still matches its purpose and its traits still exist.

5

Retired

When no flag uses it and its purpose has ended, the segment is removed, and its name is struck from shared documentation.

Who needs which permission?

ActivityTypical peopleWhy limit it
View segmentsEveryone on the projectTransparency helps people reuse existing groups
Create new segmentsDevelopers and product ownersPrevents a flood of near-duplicates
Edit shared segmentsNamed ownersAn edit reaches every flag that uses it
Delete segmentsOwners after reviewDeleting also removes the overrides that used it
Everyday analogy

A library keeps a catalogue. Without a librarian deciding what to add, what to move and what to discard, the shelves fill with duplicates and forgotten pamphlets, and finding the right book becomes a chore. Segments are a catalogue of audiences. A little regular care keeps it a help, not a hindrance.

A simple review routine

Monthly

Find unused segments

List segments that no flag references, and ask each owner whether they can be removed.

Monthly

Check trait health

Confirm every trait named in a rule is still sent by the application, under the same name.

Quarterly

Review long-lived segments

Plan, geography and entitlement segments should be rechecked against pricing and legal changes.

After incidents

Learn and adjust

When a segment caused a surprise, add a test identity that would have caught it.

i
Tip

Tie segment cleanup to flag cleanup. When a release flag is removed, ask which segments it alone was using. Often the answer is “one”, and that segment can leave with it.

22Advantages, Disadvantages and Trade-offs

Segment-based targeting is a powerful idea with real costs. Seeing both sides helps you apply it where it pays.

Advantages

  • One definition of an audience, reused on many flags
  • Gradual, controlled releases to small groups first
  • Changes without redeploying code
  • Different behaviour for staff, testers and customers in the same release
  • Stable, repeatable assignment for fair experiments
  • Clear history of who changed an audience and when

Disadvantages

  • Rules depend on the quality of the traits sent by your apps
  • Shared edits can affect many flags at once
  • Complex rule trees are hard to read and review
  • Missing data produces surprising results
  • Every extra segment adds a path to test
  • Traits are personal data that must be protected

Rules in Flagsmith or logic in your own code?

Sometimes it is not obvious whether a decision belongs in a segment rule or in your own application. A useful guideline is to ask who needs to change it, and how often. If a product manager should be able to widen an audience without a developer, or the answer changes weekly, a segment is a good home. If the decision involves complicated business logic, many data sources or strict security, keep it in code, and send the final yes-or-no result to Flagsmith as a simple trait that segments can use.

DecisionBetter in a segmentBetter in your code
Who sees a new screen firstYes, it changes often and needs no developerNo
Which plan a customer has paid forNo, it is a billing factYes, send the plan as a trait
Whether a user may access private dataNoYes, enforce on the server
What percentage of users get a trialYes, split rules are built for thisNo
Eligibility computed from many systemsOnly as a final yes-or-no traitYes, compute where the data lives
Everyday analogy

A company’s dress code can be posted on a noticeboard and updated by the office manager whenever needed. But the question of who is allowed into the vault is not decided by a noticeboard, it is decided by the security system. Both are rules about people. Choosing the right place for each rule is a matter of how often it changes and how much harm a mistake does.

!
Watch out

The more logic you put inside segment rules, the more your business behaviour hides inside a dashboard that code reviewers rarely see. Keep rules simple enough that anyone on the team can read them aloud in one breath.

23Best Practices and Common Mistakes

Experienced teams repeat a short list of habits. Newer teams repeat a short list of mistakes. Here are both.

Habits worth building

1

Agree a trait dictionary

Keep one shared list of every trait name, its type and its allowed values. Treat it as the contract between your applications and your rules.

2

Write the audience as a sentence first

Describe it in plain words before opening the dashboard, and paste that sentence into the segment’s description.

3

Keep segments small and named by purpose

One idea per segment, with a name that tells you why it exists.

4

Test the edges, not only the middle

Include boundary values, missing traits and wrong-case values in your test identities.

5

Order overrides on purpose

Narrow and special first, wide and general last, with exclusions above inclusions.

6

Review shared edits like Production edits

A segment change reaches every environment and every flag that uses it.

7

Retire what you no longer need

Remove unused segments and overrides, so the list reflects what is real today.

Mistakes to catch early

Mistake

Forgetting to identify the user

The flag returns defaults and the segment appears broken, when it was never evaluated.

Mistake

Comparing versions as text

Version 4.10 sorts below 4.2 as text. Use the version-aware comparison.

Mistake

Mixing up “none” and “not all”

A “none” rule excludes anyone matching any listed condition, not only those matching all of them.

Mistake

Over-matching with “contains”

Short fragments match unintended words. Prefer exact values and lists.

Mistake

Letting the identifier change

Switching between anonymous and logged-in IDs moves people between percentage groups.

Mistake

Trusting client traits for security

Traits from the user’s device can be edited. Enforce real access on your server.

i
Tip

Print the “habits” list and the “mistakes” list and pin them next to the team’s release checklist. Short, visible reminders work better than long documents nobody reopens.

24A Complete Worked Scenario

To finish, here is one imaginary feature taken from idea to full release, using everything in this guide.

BrightCart, the imaginary online shop, wants to launch “express reorder”, a button that lets loyal customers repeat a past order in one tap. The team wants staff to try it first, then a beta group who opted in, then ten percent of loyal customers on supported mobile apps, and finally everyone loyal. Nobody who is a test account should ever count in the numbers.

1

List the traits

The application already sends is_staff, is_test, beta_optin, orders, platform and app_version. All are agreed in the trait dictionary, with fixed types.

2

Create four small segments

“Internal staff” (is_staff equals true), “Reorder beta” (beta_optin equals true), “Loyal on supported apps” (orders at least 10, platform in ios and android, app_version at least 4.2.0 as a version comparison, and a “none” rule excluding is_test), and “Loyal supported ten percent”, which adds a percentage split of ten to the same conditions.

3

Test with the identity matrix

Test identities include a staff member, an opted-in tester, a loyal customer on version 4.10.0, one on version 4.1.9, a customer with nine orders, one with exactly ten, a test account and someone with no orders trait. Each is checked against the expected result.

4

Attach overrides in order

On the express-reorder flag in Staging: staff first, beta second, the ten percent group third. Everyone else gets the default, which is off.

5

Promote to Production in steps

The same overrides are created in Production, starting with staff only. A day later the beta group is switched on. After a quiet week, the ten percent override is enabled.

6

Widen with confidence

The ten percent segment is replaced with a fifty percent split, then with the plain “Loyal on supported apps” segment. Because assignment is stable, nobody who had the button loses it as the audience grows.

7

Clean up

When the feature is permanent, the flag is removed. The two single-purpose segments, “Reorder beta” and the ten percent group, have no flags left and are deleted. “Internal staff” stays, because many flags use it.

i
Note

Look at the order in step four. Staff sit above beta, and beta above the percentage group, so a staff member who also falls in the ten percent split still receives the staff override. Order is part of the design, not a detail.

What would have gone wrong without the routine?

Suppose the team had compared versions as text. Customers on version 4.10.0 would have been judged older than 4.2.0 and excluded from the feature, while customers on 4.1.9 might have received a button their app could not display. Suppose the team had forgotten the “none” rule on test accounts. The ten percent group would have included automated tests, distorting every number the team measured. Suppose the team had used a percentage split on an identifier that changes at login. Customers would have seen the button appear and vanish as they signed in. Each of these is an ordinary mistake, and each is caught by the habits in this guide.

25Segments with Remote Values and Multivariate Flags

Segments do more than switch features on and off. They can also change the value a flag carries, and even choose between several variants.

Remote values per audience

A Flagsmith flag can carry a value as well as an on or off position. The value might be a banner message, a number such as a maximum upload size, or a small block of settings. A segment override can supply its own value, so different audiences receive different values from the same flag. For example, a flag named upload-limit might carry fifty megabytes for everyone, two hundred for the premium segment and five hundred for the enterprise segment. The application asks one question and each customer receives the answer suited to them.

This is a tidy way to express entitlements and limits. The code reads a single flag and uses whatever number comes back. Pricing and product teams can then adjust each audience’s limit without asking for a new release. The price of this convenience is that the meaning of each value must be agreed in advance, since the application trusts whatever arrives.

Everyday analogy

A hotel safe has one keypad, but the maximum luggage weight printed on the baggage tag differs by room class. The rule “ask the front desk for your allowance” is the same for everyone, and the answer depends on who you are. A flag with segment-specific values behaves like that desk: one question, an answer tailored to the guest.

Multivariate flags and segments

A multivariate flag has several variants, such as three versions of a button, each with a share of the audience. Segment overrides interact with this in a simple way. A segment override can choose its own enabled state and value, and it takes priority over the environment’s default split for people in that segment. Members of a staff segment might always see variant B so designers can inspect it, while the public sees the default percentage split between variants A, B and C.

Use

Different limits by plan

One flag, one value per plan segment, no code change when pricing shifts.

Use

Tailored messages

A banner text for trial users and a different text for long-time customers.

Use

Pinning a variant for testers

Staff always see a chosen variant so they can review it, while real users are split.

Use

Region-specific settings

Different timeouts or partner choices for different countries from the same flag.

Cautions

Segment values multiply the number of situations you must test. A flag with four segment values has at least five answers, including the default, and each must be right. Keep value formats strict, such as a plain number or a short fixed word, and have your code validate what it receives, falling back to a safe default when a value is missing or unexpected. A mistyped value in a dashboard should never be able to break a page.

SituationWhat the user receivesWhy
Identity has a personal overrideThe personal valueIdentity overrides come first
User is in the first matching segmentThat segment’s valuePriority order picks the first match
User is in no override segmentThe environment default, or its variant splitNothing more specific applies
Segment value is empty or malformedWhatever the code does with itValidate and fall back in code

Real-world example: entitlements as configuration

Software companies that sell tiered plans, such as the many developer-tool vendors that offer free, team and enterprise levels, commonly express limits and feature access as configuration read at run time instead of fixed in code. Treating a plan’s allowances as values attached to an audience is the same idea, and it lets pricing change faster than releases.

!
Watch out

Values are visible to client apps that ask for them. Never store a secret, a private address or a confidential price in a remote value delivered to a browser or phone, even for a small segment.

26Segments for Rollouts, Experiments and Kill Switches

The same segment tools serve three quite different jobs. Knowing which job you are doing tells you how to build the rules.

Job one: gradual rollouts

A rollout widens an audience over time until everyone has a feature. The audience should grow, never flicker, and be easy to reverse. Segments built around a percentage split fit this job, with staff and beta groups above them. Success is judged by technical health: errors, speed and support messages. The segment rules should be simple, because you will be editing them often while watching the numbers, and a complicated rule makes every edit risky.

Job two: experiments

An experiment compares groups to learn which version of something works better. Here fairness matters more than speed. People must be assigned to groups in a way that is random with respect to anything that might affect the result, and they must stay in their group for the whole test. A percentage split on a stable identifier gives exactly this. Avoid building experiment groups from traits such as “most active customers”, because the groups would differ before the experiment starts, and any difference in results might come from that, not from your change. Do not edit the split while the experiment runs.

Job three: kill switches and exclusions

A kill switch is a flag that lets you turn off a risky or costly behaviour quickly. Segments help by letting you turn it off for only part of the audience, for example a single country where a partner service is failing, instead of for everyone. The rules for a kill-switch segment should be as plain as possible, so that anyone on call can read and apply them without hesitation in the middle of an incident.

JobBest segment shapeKey concernAvoid
Gradual rolloutStaff, then beta, then growing percentageSafety and reversibilityComplicated rules that are hard to edit quickly
ExperimentStable percentage split with exclusionsFair, unchanging groupsGroups chosen by behaviour, or edits during the test
Kill switchPlain, broad rules such as a country or platformSpeed and clarity under pressureNested rules nobody can read at night
EntitlementPlan-based, long-livedAccuracy with billing dataClient-supplied traits as the only source
Everyday analogy

A hospital uses the same building for emergencies, planned surgery and research trials, but each is run differently. The emergency room is built for speed and clarity, the surgical theatre for careful preparation and the trial for fair, unchanging groups. Segments are one tool serving three very different purposes, and the way you build them should match the purpose.

Keeping the three jobs apart

A common source of confusion is using one segment for two jobs. A segment created for an experiment is later reused as a rollout audience, and then someone edits its percentage mid-test. Give each job its own segment, named for its purpose. When the job ends, retire the segment with it. This small discipline prevents accidental damage to results and keeps every audience’s history clear.

Rollout

Name it for the feature

For example, “express-reorder-rollout”. It will be deleted when the feature is fully released.

Experiment

Name it for the question

For example, “checkout-button-colour-test”. It will be frozen while the test runs and archived afterwards.

Kill switch

Name it for the risk

For example, “partner-payments-disabled”. It is simple, visible and rehearsed.

Real-world example: the dark launch

Facebook has publicly described launching Chat in 2008 as a dark launch, in which the code ran for real traffic before users could see the feature, and exposure widened step by step. That is a rollout built from audience rules. The same company has also described careful, separate experiment groups for measuring changes. Treating rollouts and experiments as different jobs, even when the tools overlap, is a habit worth copying.

i
Tip

Before building any segment, write down which of the three jobs it serves. If the honest answer is “two of them”, you probably need two segments.

27Frequently Asked Questions

Short, direct answers to the questions people ask most often about segment rules.

Q1What is the difference between a segment and a trait?
A trait is a single fact about one user, such as their plan. A segment is a named group defined by rules about traits, such as “premium customers”. Traits describe people, segments describe audiences.
Q2Do segments work for anonymous visitors?
Segments are evaluated for identified users. If your application does not tell Flagsmith who the user is, it can only return default flag values. Identify the user, even with a temporary stable ID, if you need segment rules to apply.
Q3How do I express AND and OR?
An “all” rule means every condition inside must be true, which is AND. An “any” rule means at least one must be true, which is OR. Several top-level rules in one segment combine like AND.
Q4How do I express NOT?
Use a “none” rule, which is true only when no condition inside it is true, or use negative operators such as “not equals”. Where missing traits are possible, test the negative wording carefully, because absent values may behave unexpectedly.
Q5Why does my version comparison give odd results?
Versions such as 4.10.0 are not ordinary numbers or text. Use the version-aware comparison in your Flagsmith version, and test with a version ending in ten against one ending in two.
Q6Is the percentage split random?
It looks random but is repeatable. Flagsmith scrambles the user’s identifier with something specific to the segment, so the same user always lands in the same place, and raising the percentage keeps earlier users included.
Q7What happens when a user belongs to several segments?
For each flag, Flagsmith checks the segment overrides from the top of the priority list and uses the first segment the user belongs to. A personal identity override beats all segments, and the environment default applies when nothing matches.
Q8Does editing a segment affect every environment?
Yes, segment definitions are shared across the project. Overrides are separate in each environment, but a changed rule changes who matches everywhere that segment is used.
Q9Can I target a specific list of users?
You can, with identity-based conditions or personal overrides, but long pasted lists go stale quickly. For anything beyond a few people, send a trait from the system that already maintains the list and write one simple condition on it.
Q10Should I use regular expressions?
Only when exact matches, lists or “contains” cannot express the rule. Keep patterns short, test them on matching and non-matching samples, and remember that complicated patterns can be slow.
Q11How quickly do segment changes take effect?
It depends on caching and refresh settings in your SDKs. Server-side SDKs using local evaluation refresh on a timer, often around a minute by default. Measure the delay in your own system and wait one period before judging a change.
Q12Is it safe to use segments to protect paid features?
Not on their own. Traits sent from client apps can be edited by the user. Enforce real access on your server using trusted data, and use segments for presentation and gradual rollout.
Q13How do I test a segment safely?
Use permanent test identities that represent the typical member, each failing condition, a boundary value, a missing trait and an excluded group. Check the flag values for each before and after every edit.
Q14When should I delete a segment?
When no flag uses it and its purpose has ended. Confirm with the owner, check that no overrides depend on it, and remember that deleting a segment also removes its overrides.

28Summary and Key Takeaways

Segments turn “who should see this?” into a precise, reusable, testable answer. A few clear ideas carry nearly all of the value.

Key Takeaways

  • Segments are reusable audiences. Built from rules, which hold conditions, which compare traits with values, they define a group once so many flags can use it.
  • Know your connectors. “All” means AND, “any” means OR, “none” means NOT ANY, and several top-level rules combine like AND. Write the audience as a sentence first.
  • Data quality decides everything. Identify the user, send traits with consistent names and real types, and test for missing, mixed-case and boundary values.
  • Choose operators with care. Prefer exact operators and positive lists, use the version-aware comparison for app versions, and treat regular expressions and “contains” as sharp tools.
  • Percentage splits are stable. The same identifier always lands in the same place, so rollouts widen without taking features away, as long as the identifier never changes.
  • Order decides overlaps. Identity overrides win, then segment overrides from the top of the list, then the default. Put narrow and special audiences first.
  • Test, protect and tidy. Keep permanent test identities, never trust client traits for security, send the minimum personal data, and retire segments nobody uses.