Percentage Split Within a Segment in Flagsmith
A complete, plain-English guide to releasing a feature to exactly the share of the right people you choose: how the split condition works, why the same user always lands in the same place, how to combine it with other rules, how to ramp it up safely, and how to test, measure and debug it.
Suppose your team has finished a new payment screen. Showing it to every customer at once feels reckless, because a hidden fault would hurt everyone. Showing it to nobody wastes the work. What you want is a middle path: show it to a small, carefully chosen slice of the right customers first, watch what happens, and widen the slice only when the evidence says it is safe. The tool that makes this possible in Flagsmith is the percentage split, and its most useful form is a percentage split placed inside a segment.
Flagsmith is an open-source feature flag and remote configuration service. A segment is a saved description of a group of users, and a percentage split is a special condition that is true for a chosen share of users. Put the two together and you can say something precise, such as “ten percent of premium customers in India who use a recent app version”. The sentence has two layers. The segment’s ordinary rules decide who is eligible. The split decides how many of those eligible people are included right now.
This guide starts with the first idea and builds step by step. You will learn what the split really calculates, why a person never flickers in and out, how to combine the split with other conditions, how to cut audiences into slices, what the arithmetic of small numbers does to your results, how to ramp a rollout, how to run fair experiments and how to find the cause when something looks wrong. No prior knowledge is assumed and no code is needed. Menu names and some options vary between versions and plans, so treat screens described here as signposts and confirm details in your own dashboard and the official documentation.
1Why Gradual Exposure Exists
Releasing to everyone at once is the riskiest way to ship software. Releasing to a slice first is the habit that makes modern teams calm.
The cost of a big bang
In a traditional release, new behaviour reaches all users at the same moment. If it contains a mistake, every user meets that mistake together, the support queue floods and the team scrambles to fix or reverse it under pressure. Even a small fault becomes large simply because of how many people it touches. Software teams call this the blast radius: the number of users affected when something goes wrong.
Shrinking the blast radius
Gradual exposure shrinks the blast radius on purpose. If the new payment screen goes first to one percent of customers, a hidden fault harms one percent, not all of them. The team sees the problem in graphs, switches the feature off for that small group and fixes it calmly. Nobody else ever knew. The cost of learning about the fault drops by a factor of one hundred, and learning early is what a rollout is for.
A restaurant adding a new dish to the menu does not print ten thousand menus and train every waiter before tasting it. The chef serves it to the kitchen staff, then to a single table, then to a section of the dining room. Each step teaches something, and a mistake costs one unhappy table instead of a full restaurant. A percentage split is the digital version of “try it on one table first”.
What is a percentage split?
A percentage split is a rule that is true for a chosen share of users, such as five percent or fifty percent. It does not look at a user’s plan, country or age. It looks at the user’s identifier, turns it into a repeatable number and checks whether that number falls inside the chosen share. The result looks random, yet it is completely predictable for any one person, which is exactly the combination a rollout needs.
What does “within a segment” add?
A split on its own selects a slice of everyone. That is often too blunt. You may not want a random tenth of all users, including people whose apps cannot show the screen or who live in a country where the feature is not licensed. A segment lets you describe the eligible people first, and the split then selects a slice of those. The first layer protects you from showing the feature to the wrong people. The second layer protects you from showing it to too many of the right ones.
Real-world example: Facebook’s dark launch of Chat
Facebook has publicly described launching its Chat feature in 2008 as a “dark launch”, in which the code ran on real traffic before users could see it and exposure was widened in stages. Careful, staged exposure to growing audiences is the pattern that a percentage split makes routine for any team, not only for companies with their own in-house tools.
Whenever you are about to release something, ask one question first: “If this is wrong, how many people see it?” A percentage split inside a well-chosen segment lets you answer with a number you picked, not a number you hope for.
2The Vocabulary: Ten Words You Need
A small set of terms describes everything in this guide. Learn them once and every later chapter reads easily.
Identity
A single user as your application describes them to Flagsmith, with a unique identifier that should never change for that person.
Trait
A named piece of information about an identity, such as plan or country, which segment rules compare against values.
Segment
A named, reusable audience defined by rules and shared across a project.
Condition
A single yes-or-no check inside a rule, such as “plan equals premium” or “percentage split is ten”.
Percentage split
A condition that is true for a chosen share of identities, decided by a repeatable calculation.
Hash
A mathematical function that turns any input into a fixed-looking, evenly spread number, always the same for the same input.
Bucket
The number between zero and one hundred that a person’s hash produces. The split compares this number with your threshold.
Threshold
The percentage you type into the condition. People whose bucket is at or below it are inside the split.
Ramp
The planned sequence of increasing thresholds over days or weeks, such as one, five, twenty-five, fifty and one hundred.
Segment override
A setting on a flag, in one environment, saying what members of a segment should receive.
flowchart TD
SEG["Segment: Premium customers in India"] --> RG1["Rule group ALL: eligibility"]
SEG --> RG2["Rule group ALL: the slice"]
RG1 --> C1["Condition: plan equals premium"]
RG1 --> C2["Condition: country equals IN"]
RG1 --> C3["Condition: app version at least 4.2.0"]
RG2 --> C4["Condition: percentage split is 10"]
SEG -. "used by" .-> OV["Segment override on a flag in one environment"]
Read the figure from the top. One segment holds two rule groups. The first group describes who is eligible: premium plan, in India, on a recent app version. The second group holds the percentage split, which picks a share of people. Because top-level rule groups combine like the word AND, a person must pass both groups to belong to the segment. The dotted arrow shows that a flag uses the whole segment through an override, so the flag never needs to know how the audience was built.
Think of a lottery for tickets to a concert, open only to season-pass holders. First comes the eligibility check at the door: do you hold a season pass? Then comes the draw among those who do: ten percent win. The pass check is the segment’s ordinary rules. The draw is the percentage split. A person without a pass never enters the draw, and a pass holder who loses the draw simply stays outside this round.
Segments are defined once at the project level, so the same split definition exists in every environment. The flag’s override, which decides what members receive, is stored separately in each environment. Chapter 21 returns to this point because it affects how you promote a rollout.
3What “Percentage Split Within a Segment” Really Means
The phrase hides two separate decisions. Keeping them apart in your mind prevents most confusion.
Decision one: who is eligible?
Eligibility is answered by ordinary conditions on traits. A premium customer in India on a recent app is eligible. A free customer in the United States is not. Eligibility depends on facts about the person, facts that can change over time: a customer may upgrade, move country or update their app. When a fact changes, eligibility changes with it.
Decision two: are they in the slice?
The slice is answered by the percentage split and depends only on the person’s identifier, not on any trait. A person who is in the ten percent slice today is in the ten percent slice tomorrow, whatever their plan or country. The slice is a fixed property of the identifier, mixed with something unique to the segment. It changes only when you change the threshold.
Putting the two decisions together
A person belongs to the segment only when both answers are yes: eligible, and inside the slice. Since the slice has nothing to do with traits, it picks roughly the same share of every group. So if you ask for ten percent and there are twenty thousand eligible customers, you can expect about two thousand of them, give or take a small statistical wobble that Chapter 9 explains. You do not get ten percent of everyone, you get ten percent of the eligible group.
| Person | Eligible? | Inside the ten percent slice? | In the segment? |
|---|---|---|---|
| Asha, premium, India, recent app | Yes | Yes | Yes |
| Ben, premium, India, recent app | Yes | No | No |
| Chitra, free plan, India | No | Yes | No |
| Dev, free plan, United States | No | No | No |
The table shows all four combinations. Only Asha passes both checks. Ben is eligible but happens to sit outside the slice, so he sees nothing yet. Chitra sits inside the slice but is not eligible, so the slice cannot help her. Dev fails both. This is why the order of thinking matters: the slice never overrides eligibility.
A school offers a trip to Year 9 pupils only, and then picks every tenth name from the Year 9 register by a fixed rule. A Year 8 pupil whose name falls on the tenth position is still not going, because the year check comes first. A Year 9 pupil who is not on a tenth position stays behind this time, but would go if the school raised the share to twenty percent.
Why not simply make the segment smaller by rules?
You might ask why anyone needs a split at all, since rules alone can shrink an audience. A rule such as “customer number ends in 7” would do something similar. The reasons to prefer the split are practical. It is designed to spread people evenly and fairly, it is simple to widen from ten to twenty percent in one edit, and it does not require any special trait to exist. Rules based on real traits describe meaning. A split describes a quantity.
Say each segment aloud as two sentences: “These are the people who qualify” and “We include this share of them.” If you cannot say it in two plain sentences, the segment probably mixes concerns and needs splitting into smaller ones.
4How the Split Decides, Step by Step
The calculation behind a percentage split is short, repeatable and worth understanding, because every surprising behaviour follows from it.
What is a hash?
A hash function takes any input, such as a name or a number, and returns a scrambled number of fixed size. Two properties make it useful here. It is repeatable: the same input always gives the same output. And it is evenly spread: different inputs land all over the range with no pattern, so similar inputs, such as user-100 and user-101, produce unrelated outputs. You cannot guess the output by looking at the input, but you can always recompute it.
flowchart LR
A["Identity identifier"] --> M["Mix with the segment's own ID"]
S["Segment ID"] --> M
M --> H["Hash function scrambles the mix"]
H --> B["Scale to a bucket from 0 to 100"]
B --> Q{"Bucket at or below the threshold?"}
Q -- "Yes" --> IN["Condition is true"]
Q -- "No" --> OUT["Condition is false"]
Follow the figure from the left. The identity’s identifier and the segment’s own internal ID are mixed together into one piece of text. The hash function scrambles it into a large number, which is then scaled to a bucket between zero and one hundred. Finally the bucket is compared with the threshold you typed. If the bucket is at or below the threshold, the condition is true. Everything on this path is repeatable, which is why a person’s answer never changes unless the threshold, the identifier or the segment changes.
Why the segment’s ID is mixed in
If only the identifier were hashed, every split in the whole system would pick the same people. The same lucky ten percent would see every new feature, and the same unlucky ninety percent would never be the first to see anything. Mixing in the segment’s own ID gives each segment its own private scramble. Two segments, each set to ten percent, pick different tenths of the population. This is fair, and it stops unrelated experiments from landing on the same group of customers.
Threshold, in plain terms
Think of the bucket as a position along a line from zero to one hundred. The threshold is a line drawn across it. Everyone whose position is to the left of the line is in. Set the threshold to zero and nobody is in. Set it to one hundred and everyone is in. Set it to ten and about one tenth of the people, those who landed in the leftmost tenth of the line, are in.
Imagine a long corridor numbered from zero to one hundred, with every person standing at a spot the scrambling rule assigned them. Nobody can pick their own spot, and they cannot move. To choose ten percent, you simply put a barrier at spot ten and invite everyone to the left of it inside. To invite more, move the barrier right. Those already inside stay inside.
The exact way identifiers are mixed, scaled and compared is an implementation detail of Flagsmith’s rule engine, and it can differ in small ways between versions. Rely on the guarantees, which are repeatability, even spread and stability when you widen the threshold, not on the internal arithmetic.
5Why Stable Assignment Matters
Anyone can pick ten percent of users at random. The hard part is picking the same ten percent every time.
The flicker problem
Imagine deciding on every page load, using a fresh random number, whether to show the new feature. A single visitor would see the new design on one page, the old on the next, and the new again after a refresh. The experience would feel broken. Bug reports would be impossible to reproduce, because the person who saw the problem could not see it again. Any measurement of the feature’s effect would be meaningless, since the same person would be counted on both sides.
Three promises of a good split
Repeatable
The same person gets the same answer today, tomorrow and on every device, as long as their identifier and the threshold stay the same.
Evenly spread
People are distributed with no pattern, so the slice resembles the whole group in plan, country, age and behaviour.
Nested as you widen
Everyone inside at ten percent is still inside at twenty-five. Raising the threshold only adds people and never removes any.
Why the nesting promise is so valuable
Think about what you would feel as a customer. You are one of the first to receive a new feature. A week later the team widens the audience, and your feature vanishes. You are confused, perhaps annoyed. With stable nesting, widening the audience never takes anything away from early users. They keep a continuous experience, and the team can compare how the same people behave over time.
A gradually opening theme park lets in the first ten thousand visitors, then the next ten thousand, then the next. Once you are inside, you stay inside. Nobody is escorted out to make room for someone new. If the park instead drew a fresh random crowd every hour, visitors would be thrown out and let in again at random, and nobody could plan a day. Stable nesting is the rule that keeps the park orderly.
What breaks the promises
A changing identifier
If a person has an anonymous ID before login and a different ID after, each ID has its own bucket, so the person can switch sides.
Rebuilding the segment
Deleting a segment and creating a similar one gives it a new internal ID and so a new scramble. Everyone is reshuffled.
Lowering the threshold
Reducing the percentage removes the people at the far end of the line, who are the most recently added.
Changing eligibility rules
The slice stays fixed, but a changed eligibility rule can move people in or out of the segment for a different reason.
Real-world example: consistent groups in experimentation
Google has described in public research how it assigns users to experiment groups consistently so that results can be trusted over time. The same requirement applies to any rollout: whether you are measuring or merely protecting users, people must stay where you put them.
Before your first rollout, write down which identifier your application sends, where it comes from and whether it is ever replaced. If the honest answer is “it changes when people log in”, fix that first, because every percentage in your system depends on it.
6Combining the Split with Other Conditions
A split rarely stands alone. Its power comes from what you pair it with, and so do its pitfalls.
The split is just another condition
Inside a segment, the percentage split is one condition among others. Flagsmith evaluates each condition for the person, and the rule type, “all”, “any” or “none”, decides how the answers combine. The split does not have any special authority. It is true or false for a person, like “plan equals premium” is true or false.
The usual pattern: eligibility AND the slice
The most common arrangement uses an “all” rule, or several top-level rules, so that the person must satisfy the eligibility conditions and the split. Because rules combine like AND, a person who fails either part is outside. In practice, this means that the split picks about the chosen share of the eligible group, because the scrambling has nothing to do with plan, country or any other trait.
| Segment design | Plain meaning | Approximate audience |
|---|---|---|
| Split of 10 alone | A tenth of everyone with an identity | 10% of all users |
| Premium AND split of 10 | A tenth of premium customers | 10% of premium customers |
| Premium AND India AND split of 25 | A quarter of premium customers in India | 25% of that smaller group |
| Split of 10 AND NOT test accounts | A tenth of real users | 10% of non-test users |
| Premium OR split of 5 | All premium customers, plus a twentieth of everybody else | Premium plus about 5% of the rest |
The last row shows the danger of choosing the wrong connector. With “any”, the split no longer narrows the audience, it adds to it. A person who is premium qualifies automatically, and a person who is not premium qualifies by luck of the slice. Many accidental large releases begin with an “any” where an “all” was meant.
Order does not matter, structure does
Whether the split sits first or last inside a rule makes no difference to the answer, since each condition is evaluated for the same person and the results are combined. What matters is how conditions are grouped. A split placed in the same “all” rule as the eligibility conditions behaves the same as one placed in a separate top-level rule. Choose the layout that makes the segment easiest to read, usually with eligibility in one group and the slice in another, as in Figure 1.
A prize draw says: entrants must be over eighteen and live in the city, and the winner will be chosen by a draw among those who qualify. The age and city checks come first, then the draw. If instead the rules said “over eighteen, or chosen by the draw”, then every adult in the world would qualify, together with a few lucky minors. One small word turns a narrow rule into a very wide one.
Excluding test and internal accounts
Real customers and test accounts should rarely share a rollout. Test accounts distort measurements, and internal accounts may already have the feature through a staff override. A common structure puts the split and eligibility in an “all” rule, and adds a separate “none” rule that excludes accounts with an is_test trait set to true. The person must pass every top-level rule, so a test account is always outside the segment, even when the split would have included it.
Read the saved segment aloud from the top, naming each rule type, before you attach it to a flag. “All of these, and any of those, and none of these.” If a sentence sounds wrong, the audience probably is wrong.
7Slicing the Line: Bands, Halves and Groups
A single threshold picks the left end of the line. With a little care you can cut the line into several separate slices, each for a different purpose.
The line is shared inside one segment
Every percentage split condition in the same segment uses the same scramble, so a person has one bucket for that segment. If one condition says “bucket at or below ten” and another in the same segment says “bucket at or below fifty”, then everyone in the first is automatically in the second. The two conditions are not independent. They are nested, like Russian dolls.
Making a band
That nesting lets you cut a band out of the middle of the line. Suppose you want people whose bucket lies between ten and thirty. You need “bucket at or below thirty” and also “not at or below ten”. In Flagsmith’s rule language, that is an “all” rule containing a split of thirty, together with a “none” rule containing a split of ten. People in the first ten percent are removed by the “none” rule, and people above thirty are removed by the split. What remains is the band from ten to thirty, which is twenty percent of the population.
flowchart LR
L0["Bucket 0 to 10: Band A"] --> L1["Bucket 10 to 30: Band B"]
L1 --> L2["Bucket 30 to 60: Band C"]
L2 --> L3["Bucket 60 to 100: Band D"]
L0 -. "split 10" .-> T1["Threshold at 10"]
L1 -. "split 30" .-> T2["Threshold at 30"]
L2 -. "split 60" .-> T3["Threshold at 60"]
The figure shows the line from zero to one hundred divided by three thresholds at ten, thirty and sixty. The first band covers ten percent, the second twenty, the third thirty and the last forty. Each band can be its own segment, built from one split and, for all but the first, a “none” rule excluding the band to its left. Because all of them are built from the same line, the bands never overlap and together they cover everyone.
Why bands are useful
Several variants for one audience
Give each band its own fixed value, so that part of the audience sees variant A, part sees B and the rest the default.
Holdout groups
Keep the last band, say the final ten percent, permanently out of every new feature so you can measure long-term effects against them.
Staged waves without overlap
Release to the first band this week and the second band next week, with a clear record of who was in which wave.
Fair halves for A and B
A band from zero to fifty and one from fifty to one hundred divide an eligible audience into two equal, non-overlapping halves.
A marathon starts runners in waves according to their finishing-time estimates: the first corral, the second, the third. Each runner belongs to exactly one corral, the corrals do not overlap and together they hold everyone. Bands on the percentage line are corrals. Moving the barrier between two corrals changes who starts first, but a runner is always in exactly one place.
Cautions with bands
Bands rely on all conditions sharing one segment’s scramble. If you put each band in a different segment, each has its own scramble, and the bands will overlap randomly. Build all the bands you want to be disjoint from the same segment’s line, or accept the overlap. Also, test every band edge with sample users. The edges are where off-by-one errors in thresholds live. And keep band layouts simple: more than three or four bands in one design is a sign you may be rebuilding an experimentation tool by hand.
Draw the line on paper with its thresholds before building bands in the dashboard. Label each band with its width and its purpose. If you cannot draw it clearly, you will not be able to debug it clearly either.
8Splits in Different Segments: Independence and Overlap
Real products run several rollouts at once. Knowing how their audiences overlap prevents accidental pile-ups on the same unlucky people.
Different segments, different scrambles
Each segment mixes its own internal ID into the scramble, so two segments produce unrelated buckets for the same person. A customer who sits at bucket four in one segment might sit at bucket eighty-one in another. The two lines are independent of each other. That is a deliberate design, and it is good news: your ten percent for the new checkout and your ten percent for the new search page are different ten percents.
The arithmetic of overlap
Independence lets you predict overlap with simple multiplication. If one rollout includes ten percent of customers and a separate rollout includes ten percent, the share of customers in both is ten percent of ten percent, which is one percent. The share in neither is ninety percent of ninety percent, which is eighty-one percent. The remaining eighteen percent are in exactly one of the two.
| Rollout A | Rollout B | In both | In exactly one | In neither |
|---|---|---|---|---|
| 10% | 10% | 1% | 18% | 81% |
| 20% | 30% | 6% | 38% | 56% |
| 50% | 50% | 25% | 50% | 25% |
| 5% | 5% | 0.25% | 9.5% | 90.25% |
Read any row by multiplying. For twenty and thirty percent, both is 0.2 times 0.3, which is six percent. In exactly one is twenty plus thirty minus twice the overlap, which is thirty-eight percent. In neither is eighty percent of seventy percent, which is fifty-six percent. These are expected shares, and small numbers of users will vary, as the next chapter shows.
Imagine two separate raffles at a village fair, each drawn from the same crowd with its own drum of tickets. The chance that a person wins the first has nothing to do with the second. Over many people, about one in ten wins the first raffle, one in ten wins the second, and about one in a hundred wins both. Nobody is surprised by that, because the drums are separate.
When overlap is a problem
Independence is usually healthy, but two situations call for care. The first is when two risky features interact. If both the new checkout and the new payment provider reach the same one percent, a fault might appear only when they meet, and you will not know which caused it. The second is when you are running two experiments that measure the same outcome. Overlapping groups can mix their effects. In both cases, consider running the rollouts in sequence, or build them as bands of one line, so they are guaranteed never to overlap.
When you want exact overlap
Sometimes you want the opposite: two flags that must always reach exactly the same people, such as a new screen and the new service behind it. Never build two separate segments with the same threshold, because they will not match. Build one segment and attach it to both flags, or ask whether the two flags should really be one flag. A single segment is the only reliable way to guarantee the same audience.
Real-world example: many experiments at once
Google has described in public research a framework in which very large numbers of experiments run at the same time on the same users, with careful rules about which experiments may overlap. The lesson for smaller teams is the same: overlap is not an accident to ignore, it is a design choice to make deliberately.
Cloning a segment gives the copy its own internal ID, and so its own scramble. A cloned ten percent is a different ten percent. Never assume that a copy reaches the same people as the original.
9The Arithmetic of Small Numbers
Ten percent does not mean exactly ten percent. Understanding the wobble prevents false alarms and false comfort.
A target, not a guarantee
The percentage split spreads people evenly in the long run, but it does not count them. For each person, the bucket is effectively a fair random number. Over a large crowd, about ten percent land below ten. Over a small crowd, the share can drift well above or below ten. Flip a fair coin ten times and you will often get six heads, or four. Flip it a million times and you will be very close to half. Percentage splits behave the same way.
How big is the wobble?
A simple rule describes it. For a group of n eligible people and a chosen share p, the expected number included is n times p. The typical deviation from that number, called the standard deviation, is the square root of n times p times one minus p. About two thirds of the time, the real number lands within one standard deviation of the expected one, and about ninety-five percent of the time within two.
| Eligible people | Chosen share | Expected included | Typical deviation | Likely range |
|---|---|---|---|---|
| 100 | 10% | 10 | about 3 | 7 to 13, sometimes 5 to 15 |
| 1,000 | 10% | 100 | about 9.5 | 90 to 110, sometimes 81 to 119 |
| 10,000 | 10% | 1,000 | 30 | 970 to 1,030 |
| 100,000 | 10% | 10,000 | 95 | 9,905 to 10,095 |
| 1,000 | 1% | 10 | about 3 | 7 to 13 |
The table shows two lessons. First, the relative wobble shrinks as groups grow: for a hundred people it is about thirty percent of the target, for a hundred thousand it is about one percent. Second, a tiny share of a small group is risky. One percent of a thousand people is about ten, but you might get seven or thirteen, and a single user more or less is a huge change in relative terms.
Ask ten random people whether they prefer tea or coffee and you might hear seven prefer tea, even though across the whole country the split is closer to half. Ask a thousand people and the answer settles close to the truth. A small group tells you little about the population, and a small slice of a small group tells you even less.
Practical consequences
Do not panic at small drift
If a one percent rollout of two thousand people reaches thirteen users instead of twenty, that may be chance. Investigate only when the gap is far beyond the typical deviation.
Start larger with small audiences
If your eligible group is a few hundred people, a one percent slice may contain only a handful. Begin at a larger share, such as ten or twenty, to see any meaningful data.
Expect uneven early metrics
Averages computed from a few dozen people jump around. Wait for enough volume before judging a change.
Count what actually happened
Use your own logs to know how many people really received the feature, instead of assuming the target percentage.
Before choosing a first percentage, estimate how many eligible users you have and how many events per day each produces. A first slice that yields no data in a week is not caution, it is waiting.
10Choosing the Identifier the Split Hashes
The whole mechanism depends on one piece of text. Pick it well and the split is invisible. Pick it badly and everything feels random.
What makes a good identifier?
A good identifier is unique to one subject, never changes and is available wherever flags are requested. A permanent account ID fits all three. An email address fits uniqueness but can change when a person updates their profile, and it is personal data you may prefer not to share. A session ID changes constantly and is almost always a poor choice. A device ID is stable on one device but differs between a person’s phone and laptop.
| Identifier | Stable over time? | Same across devices? | Privacy concern | Verdict for splits |
|---|---|---|---|---|
| Permanent account ID | Yes | Yes | Low if it is an opaque number | Best choice |
| Email address | Can change | Yes | High | Avoid |
| Device ID | Until reinstall | No | Medium | Fine for device-level features |
| Session ID | No | No | Low | Do not use |
| Organisation or tenant ID | Yes | Yes, for everyone in it | Low | Best for company-wide features |
The anonymous-to-logged-in problem
Many applications have visitors before they log in. Giving them a temporary ID is sensible, but if the same person then logs in and receives a different permanent ID, their bucket changes. A visitor in the slice before login might be outside it afterwards, so the feature disappears at the moment they sign in. There are two good fixes. Use the permanent ID after login and accept that features may change at that moment. Or keep the same stored ID before and after login for the same person, which requires linking the two at your end.
Splitting by company, not by person
Some products sell to organisations, and everyone in a company should see the same thing. A feature that appears for one colleague and not another causes confusion and support requests. In that case, use the organisation’s ID as the identifier the split hashes. Everyone in the same company then lands in the same bucket, and the whole company is in or out together. The trade-off is that your slice is made of companies, so a few very large ones can swing your numbers a lot.
A school choosing which pupils go on a trip can pick by pupil number, which treats each pupil separately. Or it can pick by class, which keeps classmates together. Neither is wrong. Picking by pupil is fairer to individuals, while picking by class avoids splitting friends. Choosing the identifier for a split is the same decision: what is the “unit” that should be in or out together?
Do identifiers carry across environments?
Do not assume that the same person lands on the same bucket in Staging and Production. Flagsmith’s rule engine may combine the identifier with environment-specific information before hashing, in which case the same text produces a different bucket in each environment, and in any case the segment may carry different internal details. Treat the buckets as belonging to one environment, and do not use Staging results to predict exactly who will be in a Production slice. Confirm the behaviour of your version in its documentation.
Never use an identifier with a visible pattern, such as sequential numbers, as a stand-in for fairness. The hash hides the pattern, but if you also choose to use modulo or ranges on the raw number elsewhere, early customers and recent customers may form lopsided groups.
11Raising and Lowering the Percentage
Changing the threshold is the most common edit you will make. Its effects are asymmetric, and the difference is worth knowing before the first emergency.
Raising: calm and additive
When you raise the threshold, the barrier on the line moves right, and people between the old and new positions become members. Nobody who was already a member loses the feature. Raising is therefore the gentle direction. Customers experience either no change, if they were already in, or the arrival of something new, if they were just added.
Lowering: abrupt and uneven
When you lower the threshold, the barrier moves left, and the people between the new and old positions lose the feature. Lowering from fifty to ten removes eighty percent of the members at once, and they are the people who were most recently added. They may have started to rely on the feature, may have unsaved work involving it or may have already given feedback about it. A sudden removal can be as disruptive as a bug.
flowchart TD
A["Current threshold is 25"] --> B{"What do you want?"}
B -- "Widen audience" --> C["Raise threshold, for example to 50"]
C --> C1["Earlier members keep the feature"]
C1 --> C2["New members arrive in the band 25 to 50"]
B -- "Narrow audience" --> D["Lower threshold, for example to 10"]
D --> D1["Members in the band 10 to 25 lose the feature"]
D1 --> D2["Check that removal is safe for them"]
B -- "Stop everything" --> E["Switch the flag or override off"]
The figure starts from a rollout at twenty-five percent and asks what you want. Widening means raising the threshold, which keeps everyone and adds a new band. Narrowing means lowering it, which removes the band between the new and old thresholds, so you must check that removal is safe for those people. And if the aim is to stop a problem quickly, switching the override or flag off is cleaner and faster than lowering the number, because it treats everybody the same way.
When lowering is the right tool
Capacity is strained
A new backend service is struggling under load, and shrinking the audience gives it breathing room while keeping some users.
An issue affects only some users
You suspect a segment of customers is in trouble and want a smaller sample while you investigate.
You are unsure
If the feature is unsafe, switch it off. A half-measure leaves some customers exposed to the risk.
Results look odd
Changing the audience in the middle of an experiment spoils the measurements. Pause and investigate first.
A lift at a department store is crowded. The attendant can let more people in by moving a rope along, and nobody already inside is bothered. But asking some of the passengers to step out to relieve the crowd is awkward and upsetting. If the lift is truly unsafe, the attendant stops it for everyone. Raising, lowering and switching off are three different moves, and each suits a different situation.
Plan your ramp so that you rarely need to lower. Use small steps, watch the numbers at each one and treat the switch-off as the main emergency tool.
12Designing a Ramp Plan
A ramp is a promise to yourself: we will widen only when the evidence says it is safe. Writing it down turns a hope into a procedure.
The typical shape
Most ramps follow a similar shape, starting very small and roughly doubling or more at each step. A common sequence is staff only, then one percent, five percent, twenty-five percent, fifty percent and everyone. Early steps are small because uncertainty is highest. Later steps are larger because evidence has accumulated and the cost of waiting grows. The exact numbers depend on how risky the feature is and how many users you have.
| Step | Audience | Typical wait | What you look for | Go ahead when |
|---|---|---|---|---|
| 0 | Staff only, no split | Hours to a day | Obvious breakage | Staff report no blockers |
| 1 | 1% of eligible customers | One full business day | Errors and crashes | Error rate is at baseline |
| 2 | 5% | One to two days | Speed and support contacts | No rise in either |
| 3 | 25% | Two to three days | Business metrics versus the rest | No harmful movement |
| 4 | 50% | Two to three days | Load on supporting systems | Systems stay calm |
| 5 | 100% | Then a quiet week | Long-tail problems | Retire the split and the flag |
flowchart TD
A["Staff only"] --> B["Raise to 1 percent"]
B --> C{"Healthy for a full day?"}
C -- "No" --> X["Switch off and investigate"]
C -- "Yes" --> D["Raise to 5 percent"]
D --> E{"Healthy?"}
E -- "No" --> X
E -- "Yes" --> F["Raise to 25 percent"]
F --> G{"Healthy?"}
G -- "No" --> X
G -- "Yes" --> H["Raise to 50 percent, then 100 percent"]
H --> I["Retire the split and the flag"]
The figure shows the principle: after every increase there is a pause and a question. Is the feature healthy for long enough to trust? A yes sends you up one rung. A no sends you to the same place every time, which is switching off and investigating. That single, well-known exit is the point. In the middle of an incident, nobody wants to choose between several options.
How long should each step last?
A good step is long enough to include at least one full cycle of your users’ behaviour. If your customers shop mostly on weekends, a one-day step on a Tuesday teaches you little about weekends. If your business has a monthly billing cycle, some problems only appear at month end. Choose waits based on the pattern of your own traffic, not on a generic template.
A pilot climbing to cruising altitude does it in stages, levelling off between each to check the engines and instruments before the next climb. A rushed, continuous climb saves a few minutes and removes every chance to notice a warning light. The pauses are not wasted time. They are the part of the flight where problems are noticed cheaply.
Real-world example: staged releases at scale
Netflix has talked publicly about releasing changes gradually and measuring their effect before widening them, and about automated analysis that compares a small new group against an unchanged group. The ramp in this chapter is the human-sized version of the same discipline.
Do not skip a rung because the previous one looked fine. Problems often scale with traffic in ways that small samples cannot show, such as database load or rare race conditions. Each rung tests something the earlier ones could not.
13What to Measure During a Rollout
A ramp is only as safe as the signals that guard it. Choose them before you start, not while you are anxious.
Guardrail metrics
A guardrail metric is a measurement that must not get worse while you try something new, such as error rate, response time, crash rate or the share of orders that complete. You are not trying to improve guardrails, you are trying to protect them. Before the rollout, write down each guardrail, its normal range and the value that triggers a pause. Having the line drawn in advance removes the temptation to explain away a bad number.
Success metrics
A success metric is the number you hope the feature improves, such as conversion rate or time to finish a task. Success metrics need more data and more time to read than guardrails, since the improvements are usually small and noisy. Do not widen a rollout merely because a success metric is slightly up in a small slice. Use guardrails to decide whether it is safe, and use success metrics to decide whether it is worthwhile.
Errors and crashes
Compare the rate for people with the feature against people without it, not against yesterday’s overall figure.
Speed
Watch the slow end, such as the slowest five percent of requests, because averages hide pain.
Support contacts
A rise in tickets mentioning the new feature is often the earliest warning of a usability problem.
Task completion
Does the share of people who finish the journey go up, stay level or fall?
Revenue per user
Measure per user, not in total, because total revenue changes with the size of the slice.
Load on dependencies
Databases, queues and partner services feel the new code path in proportion to the audience size.
Assignment is not exposure
A person who is in the split is assigned to receive the feature. But assignment is not the same as exposure. Someone may be assigned yet never visit the page where the feature appears. If you compare all assigned users against all unassigned users, the difference is diluted by people who never saw anything. Where you can, record an event when the feature is actually shown, and measure among those who were exposed, while still reporting how many were assigned.
A shop sends discount vouchers to one in ten customers. Some customers never open the envelope. If the shop judged its voucher by comparing all ten percent who received one against everyone else, the effect would look weaker than it really was. The honest comparison is between people who opened the voucher and similar people who did not receive one.
Compare like with like
Always compare the slice against a group that is similar and measured over the same period. Comparing this week’s slice with last month’s overall numbers mixes the effect of the feature with the effect of the calendar, holidays, marketing campaigns and seasons. The group that is eligible but outside the slice is a natural comparison, because the scramble made it statistically similar. This is a useful, rarely appreciated gift of a percentage split.
Annotate your charts with each threshold change: “25 percent at 10:40”. A vertical line labelled with the step turns a confusing wobble into a clear before and after.
14Segment Split or Multivariate Allocation?
Flagsmith has two mechanisms that both talk about percentages. They solve different problems, and it helps to know which is which.
Two mechanisms, two questions
A percentage split inside a segment answers: “Is this person in or out of an audience?” It produces a yes or no. A multivariate flag’s percentage allocation answers a different question: “Among the people who get this flag, which variant does each person receive?” It divides people between several values, such as blue, green and orange buttons, with a share for each. Both use repeatable scrambling, so assignments are stable in both cases.
| Question | Segment percentage split | Multivariate allocation |
|---|---|---|
| What does it decide? | Membership of an audience | Which variant a person receives |
| Number of outcomes | Two: in or out | Several variants |
| Can it depend on traits? | Yes, combined with other conditions | It is the flag’s own setting for the environment |
| Where is it set? | Inside a segment’s rules | On the flag, per environment |
| Typical use | Gradual rollouts and holdouts | Choosing between versions of a design |
Using them together
The two often work side by side. A flag controls a new checkout design with three variants. The multivariate allocation decides which variant a person sees. A segment with a percentage split decides who gets any treatment at all, with everyone else keeping the old design through the default. Reading this as two layers helps: the segment says “who participates”, the multivariate setting says “which version they see”.
A caution about overrides and variants
A segment override typically supplies a fixed value for its members, not a new split between variants. If you want part of an audience to see variant A and part variant B from within a segment, the usual pattern is to build separate segments, as bands of one line, each with its own fixed value. Check how your version handles segment overrides on multivariate flags, because the details of how variants are chosen for segment members can differ.
Think of a bakery giving out free samples. First it decides which customers are offered a sample at all, perhaps one in five. That is the audience split. Then, for those who are offered, it decides which flavour they receive, perhaps lemon, chocolate or plain. That is the variant allocation. Mixing up the two would leave you unable to say whether a customer received nothing because of the first decision or the second.
Who gets it
Staged rollouts, holdout groups, canary audiences, regional pilots.
Which version
Design comparisons, copy tests, algorithm choices across the audience that participates.
A controlled experiment
A segment limits participants and variants divide them, with the control group left on the default.
Real-world example: experiments inside rollouts
Companies such as Spotify and Etsy have publicly described running design and algorithm experiments on carefully limited audiences before opening them to everyone. Separating the question of who takes part from the question of which version they see keeps experiments readable and rollouts safe.
Do not edit a variant split while an experiment is running, and do not change a segment’s threshold at the same time. Each edit moves people between groups, and two edits at once make the cause of any change in the results impossible to tell.
15Where a Split Segment Sits in the Override Order
A split segment is rarely alone on a flag. Its place in the priority list decides who it can reach and who it can never touch.
How overrides are chosen
When a flag has several segment overrides and a person belongs to more than one of the segments, Flagsmith needs a tie-breaker. It checks the overrides from the top of the priority list and uses the first segment the person belongs to. A personal identity override beats all segments. If no segment matches, the environment’s default applies. So the position of your percentage segment in the list controls how much of the audience it can actually influence.
flowchart TD
A["Flag requested for an identity"] --> B{"Personal identity override?"}
B -- "Yes" --> R1["Use the personal override"]
B -- "No" --> C{"In Internal staff segment?"}
C -- "Yes" --> R2["Use the staff override"]
C -- "No" --> D{"In Excluded accounts segment?"}
D -- "Yes" --> R3["Use the exclusion override, feature off"]
D -- "No" --> E{"In Ten percent rollout segment?"}
E -- "Yes" --> R4["Use the rollout override, feature on"]
E -- "No" --> R5["Use the environment default"]
Follow the figure from the top. A person with a personal override gets that answer and nothing else is considered. Next comes the staff segment, whose members always receive the feature. Then an exclusion segment turns the feature off for accounts that must never see it. Only after those does the percentage rollout segment get its turn. Anyone who matches none of the above gets the environment default. Because staff and exclusions come first, they are never affected by the rollout’s threshold.
Ordering principles
Personal and special first
Individual overrides and narrow groups such as staff and testers go at the top, so nothing broader can override them.
Exclusions above inclusions
A segment that turns the feature off for certain accounts must sit above any segment that turns it on, or it will be ignored for people in both.
Percentage rollouts in the middle
Gradual audiences sit below the narrow and excluded groups, but above broad catch-all groups.
Broad defaults last
Wide segments such as “all paying customers” go near the bottom so they only affect people nothing narrower matched.
A concert has several queues at the gate: performers, guests with disabilities, ticket holders chosen by a prize draw and the general public. A person who qualifies for more than one is sent to the first that applies, in a written order. A performer who also won the draw goes through the performers’ gate. If the organisers swapped the order, the same person could go through a different one. The order of overrides is the written order of the gates.
A common mistake with order
A frequent error is placing the rollout segment above the staff segment. Staff who are not in the slice then fall through to the staff override, which is fine, but staff who are inside the slice get the rollout’s answer, which may differ from the staff’s. If the two overrides carry different values, staff experience becomes unpredictable. Put staff above the rollout, and make sure both overrides agree on the main value so nobody has to remember which rule applied.
Reordering overrides can change what real users see the moment you save, even though nothing about a threshold changed. Treat a priority change in Production with the same care as a threshold change, and record why.
16The Evaluation Journey: From Request to Answer
Watching one request travel from the 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 eligibility conditions
ENG->>ENG: Compute bucket and compare with threshold
ENG-->>FS: Return matching segments
FS->>FS: Apply overrides in priority order
FS-->>SDK: Return flag values for this user
SDK-->>APP: Flags ready to use
The application tells the SDK who the user is and what is known about them. The SDK asks Flagsmith for the flags that apply. Flagsmith hands the identity to its rule engine, which checks the eligibility conditions of each relevant segment and, for any segment with a percentage split, computes the person’s bucket and compares it with the threshold. The engine reports matching segments, and Flagsmith applies the overrides in priority order before returning the final values. The whole journey normally takes a fraction of a second.
No identity, no split
The split needs an identifier to scramble. If the application asks for flags without identifying the user, there is nothing to hash, and segments are not evaluated at all. The application then receives the environment’s default values. This is the most common reason a first rollout appears to “do nothing” in testing: the request was anonymous.
Local evaluation on your own server
For busy backend services, Flagsmith’s server-side SDKs offer a local evaluation mode. The SDK downloads the whole rule set, including segments, thresholds and overrides, and runs the same rule engine in your own service. Decisions become extremely fast and keep working if the network to Flagsmith is briefly interrupted. The engine is designed to give the same answers as the hosted service, so the same person should land in the same place either way, but check your SDK documentation for any differences. The trade-off is a short delay before changes arrive, because the SDK refreshes on a timer.
Phoning head office each time you want to know who is on the guest list is like asking the hosted service for every decision. Keeping a printed copy of the list at the door is like local evaluation: instant and robust, but you replace the printout now and then. Both give the same answer for the same list, they differ only in how fresh the list is.
A stable identifier
The text the split scrambles. It must be the same on every request for the same person.
Correct traits
For the eligibility part of the segment, with names and types matching the rules.
The right environment key
Overrides are read from the environment your key belongs to, not from the other environments.
Fresh enough rules
With local evaluation, the thresholds you see in the dashboard may take one refresh period to arrive.
When something looks wrong, ask three questions in order: which identifier was sent, which traits came with it and which environment key was used. More than half of all “the split is broken” reports end at one of these three answers.
17How Fast a New Percentage Takes Effect
Saving a new threshold in the dashboard is not the same as every user seeing it. Knowing the delay prevents confused panic.
Layers of memory
Between the dashboard and a user’s screen sit several layers that remember recent answers to avoid asking the same question again and again. Your application may keep flags in its own memory for a time. Client SDKs on phones and browsers may store results on the device. Server SDKs in local evaluation mode download rules and refresh them on a timer, often around once a minute by default. Any proxy or delivery network in front of Flagsmith may hold answers briefly too. The sum of these delays is the time from saving a change to the last user seeing it.
A short mixed period is normal
For a short time after you raise the threshold, some servers and devices see the old state and some the new. A person who is newly inside the slice might see the feature on one server and not on another when they reload. The mix ends once every cache has refreshed. Good applications are designed to tolerate this, behaving safely whichever answer arrives. If your feature cannot work correctly when two servers briefly disagree, the problem is the feature’s design, not the flag.
When a city changes a speed limit, the new signs go up one by one, and some drivers keep following the old limit for a while out of habit. For a short time, different drivers on the same road behave differently. Caches are the digital version of habit, and the mixed period is the time the whole city takes to notice.
Planning around the delay
Know your own numbers
Find the refresh and cache settings of every SDK you use, and write them in the runbook.
Wait one full period before judging
After a threshold change, allow at least one full refresh period before deciding the change had no effect.
Design for both states
Make sure code works safely when some servers return the old answer and others the new one.
Use switch-off for emergencies
A kill switch propagates on the same schedule, so rehearse it and know how long it takes to reach every user.
Real-world example: configuration pushed close to traffic
Companies that serve huge traffic, such as Netflix and Amazon, have publicly described designs where configuration is cached close to where it is used so that no central service is asked on every request. That makes systems fast and resilient, and also means a change spreads over a short, measurable interval, which is exactly the mixed period described above.
Do not raise a threshold a second time before the first change has fully arrived. Two quick edits within one refresh period make it impossible to know which state any given server was in when a problem appeared.
18Testing a Split Before Customers Depend on It
A split looks like a single number, but it is a rule, and rules deserve tests. The tests are cheap and catch the quiet mistakes.
Two kinds of test
Two different questions need two different kinds of test. The first is about individual people: does a specific person get the right answer? The second is about the crowd: does the share included come out close to the threshold? A split can pass one and fail the other. The first is checked with named test identities. The second is checked with many generated identities and a count.
Named test identities for the individual
Create a set of test identities, each designed to prove one thing, and keep them permanently in a non-production environment. For each, you know in advance what the flag should return. Because assignment is repeatable, the answer for a given identifier at a given threshold never changes, so you can pick, once, identities known to sit low on the line and others known to sit high, and then use them as fixed reference points.
| Test identity | What it proves | Expected at threshold 10 | Expected at threshold 50 |
|---|---|---|---|
| Low bucket, eligible | The slice includes people near the start of the line | In | In |
| Middle bucket, eligible | Widening adds people in the middle | Out | In |
| High bucket, eligible | People near the end of the line are last | Out | Out |
| Low bucket, ineligible | Eligibility is enforced even for low buckets | Out | Out |
| Test account, low bucket | The exclusion rule beats the slice | Out | Out |
| Staff member | The staff override comes first | In | In |
A crowd test for the distribution
To check the share, generate a few thousand synthetic identifiers in a non-production environment, ask Flagsmith for the flag for each, and count how many receive the feature. The count should land near the expected number, within the wobble Chapter 9 described. A count wildly different from expectation signals a problem with the rules, the identifiers or the environment. This check is worth repeating after any change to the segment’s structure, though not after a simple change of threshold.
Test the extremes first
At zero, nobody except staff should receive the feature. At one hundred, every eligible person should. Extremes expose structural mistakes before the middle can hide them.
Test the nesting
Raise the threshold and confirm that everyone who was in before is still in.
Test the share
Count across a few thousand generated identifiers and compare with the expected number and its typical deviation.
Test the exclusions
Confirm that test accounts, excluded accounts and ineligible people stay out at every threshold.
Repeat after structural edits
Changing eligibility rules, bands or override order deserves a fresh run of the same checks.
A factory testing a new sorting machine does two checks. It sends a few specially marked parcels through and confirms each lands in the right bin. Then it sends a truckload of ordinary parcels and checks that the bins fill in the expected proportions. Either test alone can be fooled. Together they give real confidence.
Keep your test identities and the script that checks them with the project, not in someone’s head. A new teammate should be able to run the whole checklist in a few minutes and trust the answer.
19Debugging: Why Is This User In or Out?
Sooner or later someone will ask why a particular person sees or does not see a feature. A calm, ordered method answers it quickly.
flowchart TD
A["Report: wrong flag value for a user"] --> B{"Was the user identified?"}
B -- "No" --> B1["Identify the user and retry"]
B -- "Yes" --> C{"Right environment key?"}
C -- "No" --> C1["Use the key for the intended environment"]
C -- "Yes" --> D{"Eligibility conditions all true?"}
D -- "No" --> D1["Correct the traits or the rules"]
D -- "Yes" --> E{"Higher priority override winning?"}
E -- "Yes" --> E1["Reorder overrides or adjust the winner"]
E -- "No" --> F{"Identifier same as usual?"}
F -- "No" --> F1["Fix the identifier so the bucket is stable"]
F -- "Yes" --> G{"Cache or refresh delay?"}
G -- "Yes" --> G1["Wait one refresh period and retest"]
G -- "No" --> H["The person's bucket is simply above the threshold"]
The figure moves from the most common causes to the least. First, confirm the user was identified, because anonymous requests skip segments. Second, confirm the key belongs to the environment you think you are looking at. Third, check each eligibility condition by hand with the person’s real traits. Fourth, look for a higher override that is winning. Fifth, check that the identifier is the one you expect. Sixth, allow for caching delay. If every check passes, the answer is often simply that the person’s bucket sits above the threshold, which is correct behaviour: they will be included when you widen.
Common symptoms and likely causes
| Symptom | Likely cause | First check |
|---|---|---|
| Nobody gets the feature | Threshold at zero, anonymous requests or wrong environment | The threshold, the identifier and the key |
| Everybody gets the feature | An “any” rule where an “all” was meant | Rule types in the saved segment |
| A person flickers between states | Unstable identifier | Which ID is sent before and after login |
| Share is far from the target | Tiny group or an unusual identifier pattern | Group size and the wobble table |
| Staff see the old behaviour | A broader override sits above the staff override | Override priority order |
| Works in Staging, not in Production | Different overrides, thresholds or keys | Compare each environment’s overrides |
| Cloned segment reaches different people | New internal ID gives a new scramble | Whether a copy replaced the original |
| Recent edit has no effect yet | Cache or refresh delay | Wait one refresh period |
A technician whose lamp will not light checks the plug, the switch, the bulb and the fuse in order, from the cheapest and most likely cause to the rarest. She does not rewire the house first. The path above follows the same habit: simple, common checks first, deep investigation last.
Build a small “debug view” into your own tooling that prints the identifier, the traits and the flag values Flagsmith returned for any user. Being able to see what was actually sent, not what you believe was sent, resolves most mysteries in minutes.
20Experiments, Fair Groups and Sample Ratio Mismatch
When a split is used to compare versions, not just to protect users, the standard of fairness rises. Small flaws can ruin the whole test.
What is an experiment?
An experiment compares two or more groups that differ in one thing, to learn whether that thing changes an outcome. The groups must be alike in every other way, or any difference in results might come from the groups themselves. This is why random assignment is the gold standard: if the groups are chosen by chance, any systematic difference between outcomes can reasonably be credited to the thing you changed.
Why a split is a good fit
A percentage split inside a segment gives you repeatable, evenly spread groups, which is exactly what an experiment needs. The group inside the slice receives the change, and the eligible group outside the slice acts as the comparison, usually called the control. Because the scramble ignores traits, the two groups should resemble each other in plan, country and behaviour.
What is sample ratio mismatch?
Sample ratio mismatch is a warning sign. If you designed a fifty-fifty split and one group ends up with noticeably more people than the other, beyond what chance explains, something is wrong with how people are being assigned or counted. Perhaps one version crashes and loses events, perhaps a bot is hitting one side, or perhaps the identifier is not what you think it is. Whatever the cause, you cannot trust the results until you find it, because the groups are no longer comparable.
| Design | Group sizes you see | Verdict |
|---|---|---|
| 50/50 of 10,000 eligible | 5,030 and 4,970 | Normal wobble, carry on |
| 50/50 of 10,000 eligible | 5,300 and 4,700 | Suspicious, investigate before trusting |
| 10/90 of 100,000 eligible | 10,080 and 89,920 | Normal wobble |
| 10/90 of 100,000 eligible | 8,400 and 91,600 | Clear mismatch, find the cause |
If you invite fifty children to split into two equal teams for a race and thirty-five end up on one side, you do not start the race. You ask why. Perhaps the line to one side was shorter, perhaps friends moved together. The teams are not fair, and any result would say more about the teams than about the race.
Rules of a fair experiment
Decide the question first
Write down what you will measure, how long you will run and what result would change your mind, before looking at any data.
Do not touch the groups mid-test
Changing the threshold, the eligibility rules or the override order moves people between groups and spoils the comparison.
Measure exposure, not just assignment
Record when the feature was actually shown, and analyse the people who saw it.
Check group sizes first
Before reading any result, compare the group sizes with the design. A mismatch means stop and investigate.
Run long enough
Cover at least one full cycle of user behaviour, such as a full week, to avoid being fooled by weekday and weekend patterns.
Real-world example: trustworthy online experiments
Microsoft’s experimentation team has published widely on sample ratio mismatch, describing it as one of the most useful automatic checks on whether an online experiment can be trusted. Any team using percentage splits for comparison can borrow the same habit: check the group sizes before believing any result.
Flagsmith’s split tools can create the groups. They are not a complete statistics package. Use your analytics tooling, or a statistician, to judge whether a difference between groups is real, and do not stop an experiment the moment the numbers look good.
21Moving a Rollout Between Environments
A rollout usually climbs from Development to Staging to Production. The split makes the climb easier in some ways and trickier in others.
The segment is shared, the override is local
A segment is defined once for the whole project, so the split rule, with its threshold, is the same in every environment. The override that uses the segment, and the flag’s default, are stored per environment. This means you may set a ten percent split in the segment while the Staging override is switched on and the Production override is not yet created. The threshold is shared, the consequence is local.
flowchart LR
SEG["Segment: Rollout, split defined once"] --> DEV["Development: override on"]
SEG --> STG["Staging: override on"]
SEG --> PRD["Production: override not yet created"]
The figure shows a single segment feeding three environments. The audience definition, including the threshold, is identical everywhere. Staging and Development already have the override switched on, and Production has not been touched, so nobody in Production receives the feature, whatever the segment says. Creating the override in Production is the real act of release.
The shared threshold is a hazard
Because the threshold lives in the shared segment, raising it in Development changes it in Production too. The Production override may still be off, which protects you today, but the moment someone switches it on, the audience is whatever the shared threshold says, perhaps far larger than intended. To avoid this, either keep the rollout’s segment dedicated to one feature and treat its edits as Production edits, or use separate segments per stage with clear names.
A company writes one policy saying the first ten percent of employees alphabetically get the new laptop. Every office applies the policy locally, deciding when to start handing out laptops. If head office changes the policy to thirty percent, every office is affected the moment it next looks, even an office that has not begun. A shared definition is powerful, and any change to it is felt everywhere.
Buckets differ between environments
As Chapter 10 noted, do not assume the same person has the same bucket in Staging and Production. Test identities that sit “in the slice” in Staging may sit outside it in Production. Always verify Production behaviour with identities tested in Production, not by transferring conclusions from another environment.
A safe promotion routine
Finish in Staging first
Prove eligibility rules, exclusions and the ramp plan with the test identities and the crowd check.
Deploy code with the Production override off
The new code path exists, but nobody reaches it, and you can check that deployment alone is healthy.
Create the Production override for staff only
Staff sit above the rollout, so they see the feature while the split is still held back by the override’s absence for others.
Enable the split override at a small threshold
Begin at the first rung of the ramp, using change approval if your plan supports it, and verify with Production test identities.
Widen step by step
Each step is its own recorded, reviewed change, with the health check before the next.
Where your plan offers scheduling for approved changes, you can plan the whole ramp ahead, with each rung applied at an agreed time. Reviewers approve the plan once, and the system applies it on time, though a human should still watch the health checks.
22Governance, Approvals and the Audit Trail
A single number in a dashboard can decide how many real customers see something new. That deserves the same care as a code change.
Why a threshold is a Production change
Raising a percentage looks small, a few keystrokes in a box. But the effect is real: thousands of customers may suddenly see different behaviour. A mistaken threshold, such as typing fifty where five was meant, can expose ten times more people than planned. Many teams treat threshold edits in Production the same way as deployments: reviewed, recorded and reversible.
Who should be able to edit what?
| Activity | Typical people | Why limit it |
|---|---|---|
| View segments and thresholds | Everyone on the project | Transparency helps people reuse and trust them |
| Create new segments | Developers and product owners | Prevents duplicates and unclear names |
| Edit shared segment rules or thresholds | Named owners | A change reaches every flag and every environment using it |
| Create Production overrides | Release owners | This is the actual act of releasing |
| Switch Production overrides off | On-call engineers | Emergency authority, reviewed afterwards |
Approvals
On plans that support change requests, an edit to a Production flag can be proposed, reviewed by a colleague and applied only after approval. That second pair of eyes catches typing slips and misunderstandings. Remember that a threshold lives in a shared segment, and your version may treat segment edits differently from flag edits. Confirm whether segment changes pass through approval on your plan, and add a team habit of review where they do not.
The audit trail
An audit log is a diary kept by the system, recording who changed what and when. It answers the questions that always follow a surprise: who changed the threshold, from what to what, and at what time. Pair it with a short comment on each change, explaining the reason. A diary that says “threshold 5 to 25” is useful. One that adds “after 24 healthy hours at 5 percent” is far more useful to the next reader.
A bank vault has a lock, a guard and a logbook. The lock is your credentials, the guard is the approval step and the logbook is the audit trail. Removing any one weakens the others. A lock without a logbook cannot tell you what happened, and a logbook without a lock only records that something went wrong.
One owner per rollout segment
Someone is named, in the segment’s description, as the person who may change its threshold.
A comment on every step
State the old and new values, and the evidence that justified the move.
Announce changes
Post each step to the team channel so support and on-call staff are never surprised.
Review after each rollout
Ten minutes on what went well and what surprised you improves the next one.
If every emergency switch-off needs an approval and the only approver is asleep, the safety process becomes a risk. Many teams allow named on-call staff to switch a Production override off without approval, and review that action afterwards.
23Privacy, Fairness and Responsible Rollouts
A split decides who gets something first. Random does not automatically mean harmless, and the people on the wrong side of a draw are still people.
Send the least data that works
The split itself needs only an identifier. Segment eligibility needs a few traits. Sending a whole customer profile to a flag service “just in case” adds risk without adding capability. Data minimisation, meaning collecting and sending only what is needed for a stated purpose, reduces privacy risk, speeds up evaluation and makes review simpler. Prefer an opaque account number over an email address, and a yes-or-no trait over a detailed history.
Fairness of who goes first
If a feature improves people’s experience, such as a faster checkout, then the slice receives a benefit that others wait for. If a feature carries risk, such as an untested payment path, the slice carries that risk on behalf of everyone else. A random split spreads both benefits and risks evenly, which is a fair default. It is worth pausing when the feature affects prices, access, eligibility or opportunity, because then who goes first has real consequences and may raise legal or ethical questions.
Prices and offers
Showing different prices to different people by a random split may be legal in one place and restricted in another. Ask your legal team.
Safety and health features
Withholding a safety improvement from a random slice for measurement may be unacceptable. Do not run experiments where harm is plausible.
Vulnerable users
Think carefully before testing new behaviour on people who depend on the service, such as users of accessibility tools.
Consent and notice
Some experiments should be described in your terms of service or privacy policy. Ask your privacy team.
Client-side visibility
When an application running on a user’s device asks for flags, it can see the answers it receives. A determined person inspecting the app may see which flags are on for them and which values they carry. Do not place secrets or private business information in values delivered to browsers and phones, and do not treat the existence of a split as a way to hide a feature that must remain confidential.
A shop that decides who receives the first batch of a new product by a lucky draw is being fair in procedure. But if the product is a medicine, or the price is higher for the unlucky, the fairness of the draw does not settle the moral question. Fair method is necessary and not always sufficient.
Good practice
- Send an opaque identifier, not an email address
- Record why each sensitive rollout exists
- Review prices and access experiments with legal and privacy colleagues
- Keep sensitive traits out of segment rules
Risky practice
- Sending full user profiles for convenience
- Random price tests with no review
- Holding back safety fixes for measurement
- Keeping traits long after their purpose ended
Laws about personal data, pricing and experimentation differ between countries and change over time. Treat this chapter as general good practice, and consult your organisation’s legal and privacy teams about the rules that apply to you.
24Anti-patterns to Avoid
An anti-pattern is a habit that looks reasonable and causes trouble later. These five are the most common with percentage splits.
What it looks like
The split hashes a session ID, a random number generated at page load or an anonymous ID that is replaced at login.
Why it hurts
People flicker between old and new behaviour, bug reports cannot be reproduced and any experiment results are meaningless.
Do this instead
Use one permanent identifier for each person, or each organisation, on every platform.
What it looks like
Someone deletes a rollout segment and recreates it with the same name and rules, to “tidy up” in the middle of a ramp.
Why it hurts
The new segment has a new internal ID and so a new scramble. Early users lose the feature and different people gain it. A stable rollout becomes a reshuffle.
Do this instead
Edit the existing segment. If a copy is unavoidable, treat it as a new rollout starting from the beginning.
What it looks like
An experiment shows promising early numbers, so the team raises the threshold from ten to thirty percent halfway through.
Why it hurts
The groups now contain different people at different times, and early and late data cannot be compared. The result is no longer a clean experiment.
Do this instead
Fix the design in advance, hold it still for the planned duration and widen only after the analysis is complete.
What it looks like
The rollout segment has no exclusion for internal and automated accounts, so a share of test traffic lands in the slice.
Why it hurts
Test accounts behave unlike real customers, distort every metric and may trigger real side effects such as emails or charges.
Do this instead
Add a “none” rule excluding a test trait, and keep automated tests in their own environment.
What it looks like
A rollout reaches one hundred percent, everyone celebrates, and the segment, override and flag stay in the system for a year.
Why it hurts
The dead code path remains, the segment misleads new team members and a stray edit could suddenly take the feature away.
Do this instead
Add removal to your definition of done: delete the split, the override, the flag and the old code path soon after full release.
Real-world example: cleaning up after releases
Engineering teams at Facebook and Google have written publicly about the importance of removing experiment and release switches once their job is done, because leftover switches make systems harder to understand and test. A rollout is not finished when it reaches everyone. It is finished when its scaffolding is gone.
25Advantages, Disadvantages and Trade-offs
A percentage split inside a segment is a strong, simple tool with real limits. Seeing both sides helps you use it where it pays.
Advantages
- Shrinks the blast radius of any release
- Repeatable assignment with no flicker
- Widening never removes the feature from early users
- Combines with eligibility rules to reach the right people only
- No need for a special trait or any extra data
- Makes fair comparison groups available for free
- Changes take effect without redeploying code
Disadvantages
- Depends entirely on one stable identifier
- Small groups give wobbly, unreliable shares
- Shared segments make threshold edits reach every environment
- Lowering the threshold abruptly removes the feature from people
- Does not replace proper statistics for experiments
- Each rollout adds a path that must be tested and later removed
- Caching creates a short mixed period after every change
Choosing the right tool for the job
| Need | Best tool | Reason |
|---|---|---|
| Roll out to a growing share of eligible people | Segment with eligibility and a percentage split | Stable, widenable, simple |
| Give a feature to a known short list | Segment on a trait, or personal overrides | The people are named, not sampled |
| Choose between several designs | Multivariate flag, limited by a segment | Variants need their own allocation |
| Hold back a permanent comparison group | A band of the line used as a holdout | Stays fixed for the long term |
| Control access to paid or private features | Server-side checks, not a split | A random slice is not a security tool |
| Switch a risky feature off everywhere | The flag or override switch | Fastest, clearest and equal for everyone |
A dimmer switch is a wonderful way to raise the light in a room slowly. It is a poor tool for deciding who is allowed into the room. Percentage splits are dimmers for audiences: they control how much, not who is permitted. Use them to widen exposure gently, and use proper checks to decide who may enter.
If a rollout has run at the same percentage for weeks with nobody planning to change it, either finish the rollout or retire it. A split with no plan has become a permanent, invisible fork in your product.
26Best 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
Pick the identifier once, deliberately
Write it down, share it and make sure every platform sends the same one for the same person or organisation.
Keep eligibility and slice separate
Eligibility in one rule group, the split in another, and a short description of each in the segment notes.
Write the ramp before you begin
Steps, waits, guardrails and the exit are agreed in advance, not invented under stress.
Exclude test and internal accounts
A “none” rule on a test trait keeps measurements clean and avoids real side effects.
Order overrides on purpose
Personal and staff first, exclusions above inclusions, the rollout in the middle, broad defaults last.
Keep permanent test identities
A set of known low, middle and high bucket identities lets anyone verify behaviour in minutes.
Record and announce every change
A comment in the audit log and a message to the team prevent surprises and speed up reviews.
Retire the split when the job is done
Delete the segment, override, flag and dead code once the feature is permanent.
Mistakes to catch early
Forgetting to identify the user
The flag returns defaults and the split looks broken, when it was never evaluated.
Using “any” instead of “all”
Eligible people qualify automatically and the split adds extra people instead of narrowing.
Expecting exact percentages
Small groups wobble. Judge by the expected deviation, not by a perfect number.
Lowering instead of switching off
A half-measure leaves some people exposed to a risky feature and confuses those removed.
Cloning and assuming sameness
A copy has its own scramble, so a cloned ten percent reaches different people.
Treating a split as security
A random slice is a rollout tool. Real access control belongs on your server.
Print the habits and mistakes lists and pin them next to your release checklist. Short, visible reminders work better than long documents nobody reopens.
27A 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, has built a one-tap “express reorder” button. The team wants staff to try it first, then ten percent of loyal customers on recent mobile apps, widening to everyone loyal. Test accounts must never count. About forty thousand customers are eligible. The application sends a permanent account ID, plus the traits orders, platform, app_version, is_staff and is_test.
Check the identifier
The team confirms that web, iOS and Android all send the same permanent account ID, and that anonymous visitors are not part of this rollout. A quick review finds one old Android build sending a device ID, so its users are excluded by the platform and version rules.
Build the segments
“Internal staff” uses is_staff. “Reorder rollout” has one rule group for eligibility: orders at least ten, platform in ios and android, app version at least 4.2.0 as a version comparison. A second group holds the percentage split, set to zero for now. A third, “none” group excludes is_test equals true.
Do the arithmetic
With forty thousand eligible customers, ten percent is about four thousand, give or take sixty. One percent is four hundred, plus or minus about twenty. A one percent first step still produces enough data in a day.
Test in Staging
Named test identities with low, middle and high buckets are checked at ten and fifty percent. A crowd of five thousand generated identifiers produces counts within the expected wobble. Test accounts stay out at every threshold.
Order the overrides
On the express-reorder flag: staff first, the rollout second, default off. Both overrides carry the same value, so no one has to remember which rule applied.
Deploy and open to staff
The new build goes live with the flag off. The Production staff override is created. Employees try the button on real accounts for a day and refund their own orders.
Ramp the split
The Production rollout override is created and the threshold raised to one, then five, then twenty-five, then fifty percent. Each rise follows a day or more of healthy guardrails: errors, speed and support tickets. Each change carries a comment and is announced in the team channel.
Respond to a surprise
At twenty-five percent, response times rise for older phones. The team does not lower the threshold. They hold at twenty-five, ship a fix for an oversized image and resume the ramp two days later. People who already had the button keep it throughout.
Finish and clean up
At one hundred percent, the team waits a quiet week, then removes the old code path, the override, the flag and the “Reorder rollout” segment. “Internal staff” stays, because other flags use it.
Look at step eight. The team met a problem and chose to pause, not to lower the percentage. Pausing keeps early users stable while the cause is fixed, and it keeps measurements comparable once the ramp resumes.
What would have gone wrong without the routine?
Suppose the team had used a session ID. Customers would have seen the button appear and vanish between visits, and support would have been unable to reproduce complaints. Suppose they had used “any” for the rule type. Every loyal customer would have received the button immediately, whatever the split said. Suppose they had rebuilt the segment mid-ramp to “tidy up”. Early users would have lost the feature, and a new random group would have gained it. Each of these is an ordinary mistake, and each is caught by the habits in this guide.
28Frequently Asked Questions
Short, direct answers to the questions people ask most often about percentage splits inside segments.
29Summary and Key Takeaways
A percentage split inside a segment turns “show it to some of the right people” into a precise, repeatable and reversible instruction. A few ideas carry nearly all of the value.
Key Takeaways
- Two layers, two questions. Eligibility rules decide who qualifies, and the percentage split decides how many of them are included right now. The slice never overrides eligibility.
- The split is a repeatable calculation. The identifier, mixed with the segment’s own ID, is scrambled into a bucket and compared with your threshold, so the same person always gets the same answer.
- Raising is gentle, lowering is abrupt. Widening adds people and never removes any. Lowering removes the most recently added, so use the switch-off for emergencies.
- Small numbers wobble. Ten percent is a target, not a promise. Estimate your group size, expect the typical deviation and start larger when eligible groups are small.
- One stable identifier decides everything. Use a permanent, opaque ID everywhere, and never rebuild or clone a rollout segment in the middle of a ramp.
- Order, exclusions and ramps are design. Put staff and exclusions above the rollout, exclude test accounts, write the ramp and its guardrails first, and change one thing at a time.
- Test, protect and clean up. Check named identities and the crowd share, review Production threshold edits, respect privacy and fairness, and retire the split when the job is done.