The Multivariate Feature in Flagsmith
When on and off are not enough. Learn how one feature can carry several versions at once, how Flagsmith shares people between them fairly and consistently, and how to use the idea for experiments, gradual changes and safe tuning.
Picture an ice cream stall that wants to know which flavour of the week customers love most. A simple sign says “Strawberry: yes or no”. That sign can answer only one question. A smarter stall hands out tiny tasting spoons of three flavours, strawberry, mango and pistachio, to different customers and counts who comes back for more. The stall did not need three stalls. It needed one stall that could serve several versions of the same thing.
Software teams face the same situation. They often want to try a green button, a blue button and an orange button, or three different wordings of a message, or two different search algorithms. A normal feature flag says “on or off”. A multivariate feature says “which one of several?”. Flagsmith supports this directly, and it takes care of the difficult part: sharing people between the versions in a way that is fair, steady and easy to change.
This guide starts from zero. Every new word is explained when it first appears, and every idea comes with a picture from everyday life. By the end, you will be able to design, run and clean up a multivariate feature with confidence.
1What Is a Multivariate Feature?
Three small ideas come first: the feature flag, the value it carries, and the word “variate”.
The feature flag
A feature flag (also called a feature toggle) is a switch inside software that decides whether a behaviour is active. The code is already deployed. The flag decides who gets to use it. Changing the flag changes behaviour without a new release.
The value
Many flags carry more than on or off. They can carry a value, such as a piece of text, a number or a small bundle of settings. Flagsmith calls this a remote configuration value. For example, a flag called “home_banner_text” might carry the sentence “Welcome back!”.
The multivariate idea
The word variate simply means “a version that can vary”. A multivariate feature is a feature that has several possible values at once, each called a variation, together with a rule that says what share of people receives each one. One feature, many versions, one fair way of dividing people between them.
A multivariate feature is a bakery that bakes the same loaf in three recipes and gives each customer a slice of one recipe at random, remembering which recipe each customer got. A plain flag is a bakery with only one recipe that is either on the shelf or not.
A multivariate feature does not create several features. It creates one feature whose value differs by person. The code asks one question, “what is the value of this feature for this person?”, and receives one of the variations.
A tiny worked example
Suppose an online shop has a button on its checkout page. Today the button says “Buy now”. The marketing team suspects other wordings might persuade more visitors to finish. They create a multivariate feature named checkout_button_label. The control value is “Buy now”. They add two variations, “Add to basket” and “Get it today”. They give each variation twenty-five percent. Half of the visitors keep seeing “Buy now”, a quarter see “Add to basket” and a quarter see “Get it today”.
Notice what the developers did not have to do. They did not build a lottery. They did not write code that remembers which visitor received which wording. They did not create three separate switches. They wrote one line that asks for the value of one feature, and Flagsmith handled the sharing, the remembering and the fairness.
Why the word “feature” and not “flag”
Flagsmith uses the word feature for the thing you manage, because one feature can have an on or off state and also a value. A multivariate feature is simply a feature that has been given extra versions of its value. In everyday speech people still say “flag”, and this article uses both words for the same idea.
| Visitor | Wording seen | Reason |
|---|---|---|
| Anil | Buy now | His bucket fell in the control range |
| Bela | Add to basket | Her bucket fell in the first variation range |
| Chen | Get it today | His bucket fell in the second variation range |
| Dana | Buy now | Her bucket fell in the control range |
2Why Teams Need More Than On and Off
An on or off switch answers “should this exist?”. Multivariate answers “which version should this be?”.
Questions that need several versions
Which design wins?
Show three checkout layouts to equal groups and compare how many people finish buying.
Which message works?
Try different headlines or button labels and see which one people click.
Which setting is best?
Compare a cache lifetime of 30, 60 and 120 seconds under real traffic.
Which engine is safer?
Send small shares of traffic to an old search engine and two new ones, then widen gently.
What happens without it
A team without multivariate support has to invent its own sharing logic. Engineers create three boolean flags, write code that picks one, and then argue about how to keep each person in the same group. It is slow, hard to read, and easy to get wrong. Multivariate moves that logic into Flagsmith, where it is visible, adjustable from a dashboard, and consistent across web, mobile and servers.
A teacher who wants to test two ways of teaching fractions could split the class by hand, write the lists on paper and hope nobody swaps seats. Or the school could provide a seating system that splits the class automatically and remembers it every day. Multivariate flags are that seating system.
What large companies teach us
Companies known for large online experiments, such as Netflix, Google, Booking.com and Microsoft, have written publicly about running many experiments at once and about needing each person to stay in the same group throughout. Their lesson is simple: measurements are only trustworthy if assignment is steady. Flagsmith is not claimed to be used by any of these companies. They are mentioned only to show why steady assignment matters.
The cost of guessing
Without testing, teams decide by opinion. The loudest voice in the meeting, or the most senior person, picks the wording or the layout. Opinions are often wrong in surprising ways. Teams that measure frequently discover that the version they disliked performs better with customers. Multivariate features turn the argument into a measurement: show each version to similar people and see what they do.
The cost of all-at-once changes
Releasing a change to everyone at once is risky. If the change contains a bug or confuses people, everyone suffers at the same moment. A multivariate feature lets the team release the change to a small share, watch what happens and widen gradually. The same tool that tests wording also protects the whole customer base from a bad release.
The cost of private tooling
Some companies build their own experiment systems. This can work, but the system needs steady care: storing assignments, handling many devices, offering a screen for non-engineers and keeping an audit trail. A shared product such as Flagsmith moves those chores to a place that the whole team can see and use, so product managers can change weights without waiting for an engineer to release code.
Engineers gain a safe way to release. Product managers gain a way to test ideas. Analysts gain steady groups to compare. Support staff gain a way to pin a single customer. One feature serves all four roles.
3The Words You Need: Control, Variation, Weight
Five small words appear everywhere on the multivariate screen. Learn them once and the dashboard becomes easy to read.
| Word | Plain meaning | Example |
|---|---|---|
| Control value | The ordinary value of the feature, used as the baseline and as the leftover for people not given a variation | Button label “Buy now” |
| Variation | An alternative value that a share of people receive | Button label “Add to basket” |
| Weight | The percentage of people who receive a variation | 30 percent |
| Allocation | The set of weights chosen for an Environment | 30, 30 and the rest control |
| Bucket | A steady number derived from a person, used to decide their variation | Bucket 41 |
The control value
The control value is what the feature normally says. In experiments, it is the baseline you compare against. In Flagsmith it is the value held by the feature itself, and anyone who is not allotted a variation receives it. Thinking of it as “what everyone would see if no experiment were running” keeps the idea clear.
Variations and weights
Each variation carries its own value and its own weight, a percentage. If one variation has weight thirty and another has weight thirty, then sixty percent of people receive a variation and the remaining forty percent receive the control value. Weights add up to at most one hundred percent. Check the current documentation for how your version displays and validates them.
pie title Sharing 100 percent of people
"Control: Buy now" : 40
"Variation A: Add to basket" : 30
"Variation B: Get it today" : 30
Imagine a pizza cut into a hundred thin slices. Each variation owns some slices, and the control owns the slices that remain. Every person is assigned one slice number, and whoever owns that slice decides which value the person sees.
Weights belong to the variations. The control does not have its own typed weight in most setups. It takes whatever share the variations leave. If you want a fifty-fifty test between control and one variation, give the variation fifty percent.
Reading the weights like a recipe
A weight plan can be read aloud as a sentence: “Out of every hundred people, thirty see the first variation, thirty see the second, and forty see the control.” If you cannot say the plan as a clear sentence, the plan is probably too complicated. Teams find it useful to write that sentence in the feature description so that anyone who opens the feature understands the experiment in ten seconds.
Rounding and small audiences
Weights are shares of a large population. With a hundred thousand visitors, a thirty percent weight gives very close to thirty thousand people. With only forty visitors, the real split may be eleven, fourteen and fifteen instead of twelve, twelve and sixteen. This is ordinary chance, not a fault. It is another reason experiments need enough people before conclusions are drawn.
| Audience size | Expected people at 30 percent | Typical wobble |
|---|---|---|
| 100 | 30 | A few people either way |
| 10,000 | 3,000 | Under two percent of the group |
| 1,000,000 | 300,000 | A fraction of a percent |
4Where Multivariate Sits in the Flagsmith Tree
Flagsmith is organised as a tree. Seeing where multivariate settings live explains why they behave the way they do.
At the top is the Organisation. Below are Projects, one per product. Beneath each Project are Environments, such as Development, Staging and Production. A feature is defined once in the Project, and its state lives in each Environment. For multivariate features, a very useful split follows: the list of variations and their values belongs to the feature in the Project, while the weights are chosen separately for each Environment.
graph TD
ORG["Organisation"] --> PRJ["Project: Store"]
PRJ --> FEAT["Feature: checkout_button_label, control = Buy now"]
FEAT --> V1["Variation A: Add to basket"]
FEAT --> V2["Variation B: Get it today"]
PRJ --> DEV["Environment: Development"]
PRJ --> STG["Environment: Staging"]
PRJ --> PRD["Environment: Production"]
DEV --> W1["Weights: A 50, B 50"]
STG --> W2["Weights: A 20, B 20"]
PRD --> W3["Weights: A 0, B 0, all control"]
| Item | Lives at | Same in every Environment? |
|---|---|---|
| Feature name and type | Project | Yes |
| List of variations and their values | Project (feature) | Yes |
| Control value | Environment state of the feature | No, can differ |
| Variation weights | Environment | No |
| Segment overrides | Environment | No |
| Identity overrides | Environment | No |
A restaurant chain prints one menu with three versions of a dish. Each branch then decides how many guests are offered each version. Delhi may try the spicy version on half of its guests, while Mumbai offers it to nobody yet. The menu is shared; the serving plan is local.
You can run a wide, generous test in Development, a small cautious test in Staging, and keep Production untouched until you are ready. The same variations exist everywhere, so nothing needs to be rebuilt.
Why not define variations per Environment?
If every Environment had its own private list of variations, Staging could drift away from Production, and a test that passed in Staging might not match what Production would serve. By keeping the list of variations with the feature, Flagsmith makes sure that every Environment knows the same set of versions. Only the sharing plan, which is naturally different in Development, Staging and Production, is chosen locally.
Promotion across Environments
A healthy path is to create the feature in Development, try every variation with test identities, copy the weights to Staging with a modest audience, and finally set Production. Because the variations already exist everywhere, promotion is only a matter of typing different weights. Some teams record each step in a checklist so that nobody skips Staging in a hurry.
Development
Large weights, many test identities, quick experiments with the code.
Staging
Production-like conditions, test identities per segment, outage rehearsal.
Production
Small weights first, then grow with evidence.
5Multivariate Versus Segments Versus Plain Flags
Flagsmith offers several ways to give different people different things. Knowing which tool fits which question avoids over-engineering.
| Tool | Question it answers | Who decides who gets what | Typical use |
|---|---|---|---|
| Plain flag | Is it on or off? | Nobody, same for all | Kill switch, maintenance mode |
| Remote config value | What value should everyone use? | Nobody, same for all | Page size, banner text |
| Segment override | What should this named group get? | Rules on traits | Premium customers, one country |
| Identity override | What should this one person get? | A teammate, by hand | Support fix, demo |
| Multivariate | Which of several versions should this person get? | Weights and a steady bucket | Experiments, gradual tuning |
The key difference
A segment is about who you are. You are in the premium group because of a fact about you. Multivariate is about chance with memory. You receive variation A because your steady bucket number happened to fall in its slice, and it will fall in the same slice tomorrow. These two ideas can be combined: a segment can restrict the experiment to one country, and the multivariate weights then share people inside that country.
A school can say “all Year 5 pupils get the new book” (a segment) or “pupils are drawn by lottery into groups, each with a different book” (multivariate). The lottery is fair and remembers the draw. The group rule depends on a fact. Both are useful, and a school can even hold a lottery within Year 5 only.
If you can describe the group in a sentence about the person, use a segment. If you want to split similar people at random, use multivariate. If you only need one answer for everyone, use a plain flag.
Combining the tools in one product
Real products use all of these tools together. A plain flag acts as the kill switch for the whole checkout page. A segment gives staff the new design first. An identity override pins one troubled customer to the old design. A multivariate feature shares everyone else between three button wordings. Each tool answers a different question, and none of them replaces the others. Learning which one fits which question is the main skill of a good flag designer.
6Creating a Multivariate Feature Step by Step
The dashboard makes the process friendly. Here is the whole journey in plain steps, with the reason for each one.
Choose the Project and Environment
Features are defined in a Project, but you will set weights per Environment. Start in Development so mistakes cost nothing.
Create the feature
Give it a clear, behaviour-based name, such as checkout_button_label. Names travel to the client, so avoid secrets.
Set the control value
Type the ordinary value, for example “Buy now”. This is the baseline and the fallback.
Add the variations
Add each alternative value, for example “Add to basket” and “Get it today”. Give them readable names.
Choose the weights
Decide what percentage of people each variation should receive in this Environment. Leave the rest for control.
Switch the feature on
A feature that is off does not serve variations in the usual way. Turn it on when you are ready to start.
Verify with test identities
Open a few identities and read the effective value to confirm each variation appears for someone.
Setting up a taste test goes in the same order: decide the product, prepare the standard version, prepare the alternatives, decide how many tasters get each, open the tasting table, and check that tasters really receive different samples.
Naming that scales
| Part | Good example | Why |
|---|---|---|
| Feature name | checkout_button_label | Describes the behaviour, not the experiment owner |
| Control value | Buy now | Matches the production default |
| Variation names | label_add_to_basket, label_get_it_today | Can be recognised in analytics reports |
| Experiment note | Ticket ID and start date in the description | Future readers understand why it exists |
Write the reason, owner and planned end date in the feature description. A multivariate feature without a note looks, a year later, like a mystery that nobody dares to delete.
A worked walk-through
Imagine you are the developer at PageTurn, the fictional bookstore. In Development you create checkout_button_label and type “Buy now” as the control. You add two variations and give them readable names. You set both weights to fifty percent just in Development, so with a handful of test identities you are almost certain to see both versions quickly. You write the small piece of code that maps each label to a displayed text, and you check that an unknown label shows “Buy now”.
Next, in Staging, you reduce the weights to twenty-five percent each and you create three test identities in different segments. You confirm that the staff segment shows the new wording and that a customer from the strategic segment always sees control. You also switch off network access for a moment in a test device and watch the page fall back to control without any error.
Only after those checks do you open Production, where you begin with five percent for each variation. You write the owner, the ticket number and a planned end date in the feature description. You add a note in the team channel with the start time. Then you watch the exposure counts and your guardrail numbers for the first hour.
A launch that follows the same calm checklist every time is a good launch. Excitement is for the results, not for the release.
7What a Variation Can Hold
A variation is just a value. What kinds of values make useful variations?
Typical value kinds
Wording
Button labels, headlines, welcome messages, email subject lines.
Quantities
Page sizes, timeouts, retry counts, discount percentages.
A named choice
A layout name such as “grid” or “list”, which the code maps to a design.
Small bundle
A short structured text holding several settings that belong together.
Prefer names over raw details
A very useful habit is to make the variation value a name that the code understands, such as “layout_grid”, rather than a long block of settings. The code then decides what “layout_grid” means. This keeps changes in code review, keeps flags small, and lets you rename the effect without touching the live configuration.
A waiter taking an order writes “table 5: dish 12” instead of a paragraph of cooking instructions. The kitchen knows what dish 12 is. A short name on the ticket keeps the system fast and safe from typing mistakes.
Keep the shape consistent
Every variation of a feature should have the same kind of value. If the control is a short label, each variation should be a short label too. Mixing a number in one variation and a sentence in another forces the code to guess what it received, which creates bugs on the exact path where you are measuring.
| Feature | Control | Variation A | Variation B | Consistent? |
|---|---|---|---|---|
| Search page size | 20 | 30 | 50 | Yes, all numbers |
| Home layout | layout_list | layout_grid | layout_cards | Yes, all names |
| Sign-up prompt | Join us | 5 | Start free trial | No, one is a number |
Client-side applications receive the value. Anything you place in a variation can be read by a curious person. Use variations for presentation and tuning only.
Reviewing values with designers
If a variation holds text that customers will read, ask a writer or designer to review it before it goes live. A typing error in a variation is seen by a real share of customers, and it can also spoil an experiment, because the wording problem is mixed with the idea being tested. A short review step costs minutes and protects the whole test.
8How Flagsmith Chooses a Variation for a Person
This is the heart of the feature. Behind the friendly dashboard is a simple, clever trick that makes the choice both random-looking and perfectly repeatable.
The goal
Flagsmith must pick a variation for each person so that the shares match the weights, and so that the same person always gets the same variation, on every device and every visit, unless the weights change. Pure random picking would break the second promise, because a coin flip gives a different answer each time.
The trick: a stable number from a hash
A hash function is a recipe that turns any text into a long scrambled number. The same text always gives the same number, but similar-looking texts give very different numbers. Flagsmith combines the person’s identifier with information about the feature, runs the recipe, and reduces the result to a number between zero and one hundred. This number is the bucket. Flagsmith then walks along the variations, each owning a range of buckets according to its weight, and the person receives the variation whose range contains their bucket. Check the current documentation for the exact recipe, because internal details can change between versions.
flowchart LR
A["Identifier: user_48213"] --> B["Mix with the feature"]
B --> C["Hash recipe"]
C --> D["Bucket number, e.g. 37"]
D --> E{"Which range holds 37?"}
E -- "0 to 29: Variation A" --> F["Variation A"]
E -- "30 to 59: Variation B" --> G["Variation B"]
E -- "60 to 99: Control" --> H["Control value"]
Imagine every person has a lucky number written on their ticket, derived from their name by a fixed recipe. A wall chart says “numbers 0 to 29 get red, 30 to 59 get blue, the rest get green”. Nobody needs to roll dice. Everyone checks their ticket against the chart, and the answer is the same every day.
Why mixing in the feature matters
If the bucket came only from the person, then the same people would land in the “first thirty percent” of every experiment, and some customers would always be the guinea pigs. By mixing in the feature, each feature reshuffles people differently. A person in the first slice of one experiment may be in the last slice of the next. This spreads the experience fairly across the customer base.
| Person | Bucket for feature 1 | Variation in feature 1 | Bucket for feature 2 | Variation in feature 2 |
|---|---|---|---|---|
| Anil | 12 | Variation A | 78 | Control |
| Bela | 45 | Variation B | 15 | Variation A |
| Chen | 83 | Control | 41 | Variation B |
What the hash does not do
The hash does not look at who the person is, what they bought or where they live. It treats the identifier as an anonymous piece of text. This is a useful property: the sharing is fair with respect to everything else about the person, so the groups tend to look alike on average. That is exactly what an experiment needs, because differences in outcome can then be linked to the version rather than to the kind of people in each group.
Two people with similar identifiers
Even identifiers that look almost the same, such as user_1001 and user_1002, produce very different bucket numbers. The hash scrambles them thoroughly. So consecutive customers do not cluster in the same group, and early sign-ups do not all end up in one variation.
Same person, two features
Because the feature is mixed into the hash, one person lands in different places for different features. This avoids a hidden problem: if a person were always in the “first thirty percent” of every experiment, they would be the first to see every untested idea. Mixing the feature spreads that burden.
When two experiments run at once on the same page, one person may be in a variation of both. The effects can combine in ways that neither test intended. For important experiments, run them one at a time, or run them on different parts of the product, or plan an analysis that includes the interaction.
9Why Identity Is Required
The hash needs something steady to work from. That something is the identity.
An identity in one paragraph
An identity is Flagsmith’s name for one end user, account or device that your application tells it about, named by an identifier, usually an internal user ID. When the application asks for flags for an identity, Flagsmith can personalise the answer. When it asks without one, Flagsmith has nothing steady to hash.
What happens without an identity
If the application asks for flags without supplying an identifier, Flagsmith cannot place the person in a bucket. In that case the person typically receives the control value of the feature, not a variation. The multivariate mechanism needs a steady name to work. Check the current documentation for the exact behaviour of each SDK.
A prize draw can only be repeatable if each ticket has a number. A person who walks in with no ticket cannot be placed in any group, so the organisers give them the standard prize. Giving every visitor a ticket, even a temporary one, makes the draw possible.
Choosing the identifier for experiments
| Situation | Good identifier | Reason |
|---|---|---|
| Signed-in product features | Internal user ID | Stable across devices |
| Public pages before sign-in | Random device ID stored on the device | Stable on that device |
| Company-wide experiments in a business product | Account ID | Everyone in a company sees the same version |
| Anything | Never a session ID or timestamp | Changes each visit, so people are reshuffled |
If a person uses your website before sign-in and the app then switches the identifier to their user ID, they may land in a different variation after signing in. Decide how you handle that moment for each experiment. Using the same device identifier throughout an experiment is the simplest fix.
Account-level experiments
In business products, everyone in one company often needs to see the same version, otherwise colleagues sitting side by side would see different screens and call support. In that case use the account ID as the identifier for the experiment. All people in a company then share one bucket and one variation. The trade-off is that you have fewer units to compare, so the test needs more companies or more time.
10Stickiness: Same Person, Same Version
Steadiness is what turns a random split into a trustworthy experiment. Understanding exactly when people stay put, and when they move, protects your results.
Staying put
As long as the identifier, the feature and the weights stay the same, a person’s bucket and variation never change. They keep seeing the same version on their phone, laptop and tablet, if all three use the same identifier.
When people move
People can move between variations when weights change, because the ranges of buckets are redrawn. Imagine ranges 0 to 29 for A, 30 to 59 for B and the rest control. If you raise A to forty percent, the range for A becomes 0 to 39, and B’s range may shift. People who were at the edges can change variation. The shift is small, but it exists.
| Change you make | Effect on people | Advice during an experiment |
|---|---|---|
| Nothing | Everyone keeps the same version | The ideal state |
| Change the text of a variation | Same people, new text | Avoid, it breaks comparisons |
| Change a weight | Some people move between versions | Avoid mid-experiment, or restart the measurement |
| Add a new variation | Ranges are redrawn, many may move | Treat as a new experiment |
| Change identifier format | Everyone is reshuffled | Never do this during an experiment |
| Set all weights to zero | Everyone receives control | The safe way to stop |
stateDiagram-v2
[*] --> Planned: Variations and weights chosen
Planned --> Running: Feature on, people bucketed
Running --> Running: Same people, same versions
Running --> Adjusted: Weights changed
Adjusted --> Running: Some people moved, measure from here
Running --> Stopped: Weights set to zero or feature off
Stopped --> [*]
If a school moves the lines that split a class into reading groups halfway through a term, a few pupils change groups. Their progress cannot be fairly compared with the earlier weeks. Experiments are like that: the cleanest data comes from drawing the lines once and keeping them.
A story of a weight change
A team starts with variation A at ten percent, variation B at ten percent and control at eighty percent. After a week the numbers look safe, so they raise A to twenty-five percent and B to twenty-five percent. Everyone whose bucket lay in the lowest ten percent for A still sees A. New people with buckets in the next fifteen percent now also see A. Some people who used to see control now see a variation, because they moved into a variation’s widened range. Some people who saw B may now see A, because the ranges are laid end to end and shifted when the first range grew.
This is why teams prefer to grow an experiment in one clear step, record the date, and later analyse the period before and after the change separately. People who stayed in the same version across both periods are the cleanest group to study.
Stopping an experiment cleanly
The cleanest stop is to set all variation weights to zero. Everybody then receives the control value at once, and no code needs to be released. If the winner is a variation, the best next step is to make its value the new control value in the same moment, so that people never see a flicker of the old version.
11The Order of Decisions: Overrides and Variations
Several rules can apply to one person at once. Flagsmith resolves the conflict with a fixed order, and multivariate sits inside it.
Three layers
The identity override is a special answer for one person. The segment override is a special answer for a named group. The Environment state is the general answer, and for a multivariate feature this is where the weighted split lives. The most specific layer that applies wins.
flowchart TD
A["Request: feature X for identity I"] --> B{"Identity override for X?"}
B -- Yes --> C["Use that exact value"]
B -- No --> D{"In a segment that overrides X?"}
D -- Yes --> E["Use the segment's value"]
D -- No --> F["Compute bucket and pick variation by weight"]
F --> G["Variation or control value"]
C --> H["Return to application"]
E --> H
G --> H
A cafeteria offers a lottery for which dessert you get. A pupil with an allergy note always gets the safe dessert, whatever the lottery says. A group like “sports team” might get a special dessert on match days. Everyone else goes through the lottery. The note and the group rule outrank luck.
Why this ordering is useful
Always see the new version
A staff segment forces the new version, so the team sees what it is building whatever the lottery says.
Fix one customer
An identity override pins a troubled customer to the safe value without ending the experiment.
Keep VIPs out
A segment of important accounts can be pinned to control so they never join an experiment.
Show a version on purpose
A sales engineer pins a demo account to a chosen variation for a presentation.
People pinned by overrides are no longer randomly assigned. If you include them in your analysis, you may bias the result. Exclude pinned identities from the numbers you compare, or record them separately.
Reading the effective value
When you open an identity in the dashboard, it shows the effective value of each feature and the reason: pinned by an identity override, set by a segment, or chosen by the weighted split. Make this the first stop whenever someone asks, “why does this person see that version?”. The answer is usually visible in under a minute and removes guesswork from the conversation.
12The Journey of One Request
Follow a single request from the app to Flagsmith and back, and the whole mechanism becomes a short story.
The cast
The application is your product. The SDK is a small library inside it that knows how to talk to Flagsmith. The Flagsmith API is the service that answers. The rules store holds features, variations, weights, segments and identities.
sequenceDiagram
participant U as Person
participant A as Application
participant S as SDK
participant F as Flagsmith API
participant R as Rules Store
U->>A: Opens the checkout page
A->>S: Get value of checkout_button_label for user_48213
S->>F: Request with Environment key and identifier
F->>R: Load feature, variations, weights, overrides
R-->>F: Rules for this Environment
F->>F: Check overrides, then compute bucket and pick variation
F-->>S: Value: Add to basket
S-->>A: Value ready
A-->>U: Shows the button labelled Add to basket
Reading the diagram
The person opens a page. The application asks the SDK for the feature value, passing the identifier. The SDK adds the Environment key, which tells Flagsmith which Environment the question concerns. Flagsmith loads the rules, checks overrides, computes the bucket and chooses the variation. The value travels back and the application draws the correct button.
It is like a visitor asking a hotel desk, “which room type is mine?”. The desk checks the visitor’s reservation and special notes, consults the allocation chart, and hands over a key. The visitor never sees the chart, only the key.
What the application actually does
The code does not contain three separate branches wired to three flags. It reads one value and acts on it, usually by choosing among a small number of known names. The control value is the safe fallback when a value is unknown or missing, so a typo in a variation cannot crash the page.
What can slow the journey
Three things commonly slow the trip: a slow network, a request made too often, and a request that waits for a response before drawing anything. The remedies are simple. Cache results, ask once per screen rather than once per element, and draw the page with the control version while waiting if a short timeout expires. Customers prefer a page that appears quickly in a safe version over a perfect page that appears late.
13Using the Value in Your Application
Getting the value is the easy part. Using it safely is where good habits pay off.
The mapping habit
Treat the incoming value as a label and map it to behaviour inside your own code. The code holds a small table: “label_add_to_basket means show this text”, “label_get_it_today means show that text”. If the incoming label is not in the table, the code uses the control behaviour. This protects against typos, unexpected values and the case where a variation is deleted while some devices still hold an older cached answer.
| Incoming value | Code behaviour | Safe? |
|---|---|---|
| label_add_to_basket | Show “Add to basket” | Yes, known label |
| label_get_it_today | Show “Get it today” | Yes, known label |
| Buy now (control) | Show “Buy now” | Yes, known label |
| Anything else | Show “Buy now” | Yes, falls back to control |
A vending machine only dispenses items for buttons it knows. If someone invents button number 99, the machine does nothing rather than throwing out random goods. Your code should behave like the vending machine: unknown label, default product.
Record what the person saw
An experiment is only useful if you can later tell who saw what. When the application receives a variation, it should send an event to its analytics tool saying, for example, “person user_48213 saw variation label_add_to_basket for feature checkout_button_label”. Without this, you cannot link behaviour to variation. Flagsmith offers integrations with some analytics tools, and many teams record this themselves. Check the current documentation for which integrations are available.
Do it once, at the moment of exposure
Record the exposure when the person actually sees the variation, not when the app merely fetches the value. If you record exposure for everyone who loaded the app but only some reached the checkout page, your comparison will include people who never saw the button.
Log exposure once per person per feature, at the point of display. Repeated logging inflates numbers and confuses the analysts.
A tidy way to read the value in code
A good habit is to wrap the Flagsmith call in a small function of your own, such as “get checkout label”, which hides the details. Inside, it asks Flagsmith, checks the answer against the list of known labels and returns control for anything unexpected. The rest of the application only calls the small function. If you later change your flag tool or the way names are stored, only that one function changes.
The wrapper is also the best place to record exposure, to apply safe defaults and to add timing measurements. One place for all the careful work means the careful work actually happens.
| Responsibility | Where it lives | Benefit |
|---|---|---|
| Ask Flagsmith | Wrapper function | One place to change |
| Check known labels | Wrapper function | Typos cannot break pages |
| Fall back to control | Wrapper function | Safe during outages |
| Record exposure | At the screen that displays the version | Only real viewers are counted |
| Map label to design | The screen code | Designers and engineers review it together |
14Designing a Good Experiment
Flagsmith splits people fairly. Whether the result teaches you anything depends on how you design the experiment around it.
Start with a hypothesis
A hypothesis is a clear sentence that can turn out wrong. For example: “Changing the button text to ‘Add to basket’ will increase the share of visitors who start checkout.” Writing it down before the test prevents the habit of looking at many numbers afterwards and picking whichever one looks good.
Choose one main measure
Pick one primary metric, such as the share of visitors who finish a purchase. Other numbers can be watched as guardrails, such as page speed or complaint rate, to make sure a win in one area does not cause harm in another.
Decide how long and how many
Small differences need many people to detect. A test run for one afternoon with a hundred visitors may show a difference that is only luck. Statisticians use a calculation called a power analysis to estimate how many people are needed. Many analytics tools provide a sample size calculator. Fix the duration in advance, and cover at least a full weekly cycle so weekday and weekend behaviour are both included.
Write the hypothesis
One sentence, one expected improvement.
Pick the metrics
One primary measure, a few guardrails.
Estimate sample size and duration
Decide when you will stop before you start.
Set weights and start
Often a fifty-fifty split between control and variation gives the fastest answer.
Do not peek and change
Looking is fine. Changing weights or stopping early because a number looks good is not.
Analyse and decide
Compare results, check guardrails, decide to ship, drop or iterate.
Clean up
Remove the unused variations and the code that handled them.
A gardener comparing two fertilisers plants both on similar beds, waits a full season, and measures the harvest. Judging after two days because one bed looks greener would be a mistake. Experiments reward patience and a plan made in advance.
Checking results every hour and stopping the moment one variation looks better greatly increases the chance of a false win. Decide the stopping point in advance, or use analysis methods built for continuous monitoring.
An example hypothesis, written well
“For visitors who reach the checkout page, changing the button label from ‘Buy now’ to ‘Add to basket’ will raise the share who complete a purchase within the same visit by at least two percentage points, without increasing the rate of customer support contacts.” This sentence names the audience, the change, the primary metric, the size of improvement worth caring about and the guardrail. Anyone can later check whether it came true.
Minimum meaningful change
Before the test, decide the smallest improvement that would justify the effort. A change that raises purchases by a hundredth of a percent is real but may not matter to the business, and detecting it would need millions of visitors. Fixing the smallest interesting change shapes the sample size calculation and prevents a long test chasing something not worth having.
Run the test through full cycles
Customer behaviour follows rhythms. Weekends differ from weekdays. Pay day differs from the end of the month. A test that runs from Tuesday to Thursday sees only part of the picture. Running at least one or two full weeks, and avoiding unusual events such as big sales unless they are the target, gives a fairer view.
Decide before, not after
| Decision | Make it | Why |
|---|---|---|
| Primary metric | Before launch | Prevents picking the best-looking number afterwards |
| Duration or sample size | Before launch | Prevents stopping early on luck |
| Who is excluded | Before launch | Keeps pinned staff and VIPs out of the numbers |
| What counts as a win | Before launch | Avoids arguing after the result |
| Who decides | Before launch | Stops drift |
15Choosing Weights Wisely
The numbers you type into the weight boxes decide how fast you learn and how much risk you take.
Common weight plans
| Plan | Weights | Best for | Trade-off |
|---|---|---|---|
| Even split | Variation 50, control 50 | Fastest answer for one change | Half the audience sees an untested version |
| Cautious split | Variation 10, control 90 | Risky changes | Slower to gather evidence |
| Three-way | A 33, B 33, control 34 | Choosing between two ideas | Each group is smaller, so you need more time |
| Staged ramp | 1, 5, 25, 50, 100 | Safe release of a change | More steps to manage |
| Holdback | Variation 95, control 5 | Checking the long-term effect after release | Few people left as comparison |
More variations, less certainty
Every extra variation divides the audience into smaller groups. With the same number of visitors, four variations give each group a quarter of the evidence. Small groups produce noisy results. Teams that want to test many ideas should either wait longer or narrow the list before the live test, using earlier research and common sense.
flowchart TD
A["All eligible people"] --> B["Weights split them"]
B --> C["Control: 50 percent"]
B --> D["Variation A: 25 percent"]
B --> E["Variation B: 25 percent"]
C --> F["Compare metric"]
D --> F
E --> F
F --> G["Decide: ship, drop or iterate"]
A teacher with thirty pupils who splits the class into two groups gets fifteen opinions per method. Splitting into six groups of five gives opinions too thin to trust. The more ways you slice the class, the less each slice can tell you.
Start with the smallest number of variations that answers your question. One control and one variation is often enough. Add more only when a real second idea deserves a fair test.
Writing the plan in the description
Put the weight plan and the reasons for it into the feature description, for instance “Variation A 25, B 25, control 50, chosen to get an answer in two weeks with ordinary traffic.” When another person opens the feature, they see the intent as well as the numbers. If the numbers later change, add a dated line to the description. This tiny journal makes the history readable to everyone, even without opening the audit log.
16Targeting an Experiment With Segments
Not every experiment should include everybody. Combining segments with multivariate lets you test on exactly the right audience.
Why limit the audience
A change meant for new customers should not be tested on veterans. A feature for one country may not make sense elsewhere. Including the wrong people dilutes results and may annoy people for no reason.
Two ways to combine
Eligible segment first
Only identities in a chosen segment are shared out by weight. Everyone else gets control. Check current documentation for how your version expresses this.
Exclusion segments
Pin selected groups, such as VIP accounts or staff, to control or to a fixed value so they stay out of the measurement.
| Goal | Segment idea | Effect |
|---|---|---|
| Test only on new customers | signup_month equals this month | Experienced users unaffected |
| Test in one market | country equals India | Other markets stay on control |
| Keep important accounts safe | account_tier equals strategic | They always see control |
| Let staff see the new version | is_staff equals true | Staff pinned to the new variation |
| Test mobile separately | platform equals android | Results are not mixed with web |
A restaurant testing a new vegetarian dish invites only its vegetarian regulars to vote. Asking every guest, including people who never order vegetarian food, would make the results meaningless.
A segment can only use facts the application sends. If the app forgets to send the country, the segment will not match, and the person silently receives control. Make sure the needed traits arrive consistently.
Keeping the audience description honest
When you limit an experiment to a segment, say so in every report: “results apply to new customers in India on Android”. It is tempting to speak as if the result applies to everyone. A finding for one audience may not hold for another, and a clear description of who was in the test prevents costly over-generalising.
17Beyond Experiments: Gradual Change and Safe Tuning
Multivariate is not only for A/B tests. It is also a safe way to change behaviour slowly and to find a good setting.
Engine migrations
A team replacing its search engine can create a feature with variations “engine_old”, “engine_new_a” and “engine_new_b”. Starting with a tiny share on the new engines, they watch speed and error rates, then grow the weights gradually. If something goes wrong, they set the new weights to zero and everyone returns to the old engine within moments.
Tuning a number
When nobody knows the best cache lifetime, a feature with variations 30, 60 and 120 seconds lets live traffic reveal the answer, guided by measurements of speed and cost. Once the answer is clear, the winner becomes the control value and the experiment ends.
Fair load testing in production
Sending a small percentage of real traffic to a new service, sometimes called a canary release, is easy with weights. The name comes from the canary birds miners once carried to warn of danger: if the small group has trouble, the team learns before everyone is affected.
flowchart LR
A["Day 1: new 1 percent"] --> B["Day 3: new 5 percent"]
B --> C["Day 5: new 25 percent"]
C --> D["Day 7: new 50 percent"]
D --> E["Day 9: new 100 percent"]
B -. "problem seen" .-> F["Set weights to zero, old engine again"]
C -. "problem seen" .-> F
| Use case | Variations | What you watch |
|---|---|---|
| Wording test | Three headlines | Clicks and sign-ups |
| Engine migration | Old and new engines | Errors and speed |
| Tuning a number | 30, 60, 120 seconds | Cost and freshness |
| Layout change | List, grid, cards | Time on page, purchases |
| Price display format | With and without tax | Basket abandonment, complaints |
A town changing the direction of a busy road first tries it on a quiet weekend, then on weekday mornings, then permanently. At each step engineers watch traffic. If trouble appears, the old direction is restored with a few cones.
A migration story in detail
RoamEasy, the fictional travel site, wants to replace its search engine. The feature search_engine has three values: “engine_old”, “engine_new_a” and “engine_new_b”. At first both new engines receive one percent each. The team compares response time, error rate and the share of searches that lead to a click. They also run a “shadow” check offline, comparing the results of the engines for sample searches, which does not involve customers at all.
When the first week shows no problems, they raise each new engine to five percent and then to fifteen. At fifteen percent, engine B shows slower answers on mobile networks. They set B to zero and keep A. A week later A reaches fifty percent, then one hundred, and the old engine is finally retired. At no moment did the team need to deploy new code to change exposure. Every step was a change on the dashboard that anyone with permission could review in the audit log.
Why the old path must keep working
A gradual migration is only safe if the old behaviour keeps working until the end. If the team deletes the old engine early, setting weights to zero no longer rescues anyone. Keep the old path alive and tested until the new one has served everyone for a comfortable period.
18Remote and Local Evaluation
Where the choice of variation is made affects speed, freshness and what you need to protect.
Remote evaluation
In remote evaluation, the SDK sends the identifier to Flagsmith and Flagsmith does the thinking. The rules never leave the server. It is the default and is simple and safe.
Local evaluation
In local evaluation, a server-side SDK downloads the Environment document, including variations and weights, and works out the answer in its own memory. It needs the secret server-side key. It avoids a network call for each decision, but its copy of the rules refreshes on a schedule, so a weight change takes a short time to arrive. Check the current documentation for which SDKs support this mode and how bucketing is kept consistent between modes.
| Question | Remote evaluation | Local evaluation |
|---|---|---|
| Who picks the variation? | Flagsmith service | Your own server |
| Network call per decision? | Yes, usually cached | No |
| Freshness of weights | At each request | As of the last refresh |
| Key needed | Client or server key | Server-side key |
| Best for | Web, mobile, general use | High-volume backends |
Remote evaluation is phoning head office for each decision. Local evaluation is keeping a printed rulebook at the counter, refreshed every morning. The phone is always current but slower. The rulebook is instant but can lag behind a change made after breakfast.
If the same person can be evaluated by both a browser app (remote) and a backend (local), test in Staging that both give the same variation for the same identifier. A mismatch would show up in your data as people flipping between versions.
A word on SDK differences
Different SDKs, for example for web, mobile and various server languages, can differ in the features they support and in the details of caching and evaluation. When your experiment runs across several platforms, read the documentation for each SDK you use, and test each one in Staging with the same identifier to confirm that the same variation appears. Differences found in Staging cost nothing. Differences found in Production cost data.
19Working With Multivariate Features in the Dashboard
The dashboard shows the whole picture on one screen. Knowing where to look saves time and prevents expensive slips.
The feature list
Inside an Environment, the features page lists every feature with its on or off state, its control value and, for multivariate features, an indicator that variations exist. Searching, filtering and tagging help when the list grows. Tags such as “experiment”, “kill-switch” or the owning team make clean-up much easier later.
The feature panel
Opening a multivariate feature shows the control value, the list of variations and the weight boxes for this Environment. A summary of what percentage of people receive each version is usually visible. Here you edit weights, update values, add segment overrides and read the change history.
Check the Environment name
Confirm you are in Production or Staging before editing anything.
Open the feature
Read the description, owner and planned end date.
Review the current weights
Know the starting point before you change it.
Make the smallest change
Edit one thing at a time and write why in the change note if the screen offers one.
Verify with a test identity
Confirm the effective value for a known person and a known segment.
A pilot reads the cockpit panel, changes one control at a time and checks the gauge after each change. The dashboard is a cockpit for your product’s behaviour: calm, deliberate moves beat rapid fiddling.
Permissions
Not everyone should be able to change Production weights. Flagsmith lets administrators grant permissions per Environment and per Project. A sensible pattern is wide freedom in Development, some freedom in Staging and a small trusted group in Production. Some plans also offer change requests, where a second person approves a Production change before it takes effect. Check the current documentation for what your plan includes.
Automation
The Flagsmith API lets scripts create features, edit variations and adjust weights. This is useful for staged ramps that follow a timetable, but automation should be limited, logged and reviewed. A script that raises weights automatically must also have a way to lower them when a guardrail metric worsens.
Tags and naming for large teams
A big organisation may have hundreds of features. Tags such as “experiment”, “migration”, “ops” and the owning team name keep the list navigable. A short naming convention helps even more: start names with the area of the product, such as checkout_ or search_, so related features sort together in the list.
20The Lifecycle of a Multivariate Feature
A multivariate feature is meant to be temporary. Knowing the stages makes sure it leaves cleanly.
stateDiagram-v2
[*] --> Proposed: Idea and hypothesis
Proposed --> Built: Feature, variations, code mapping
Built --> Testing: Weights in Development and Staging
Testing --> Live: Production weights set
Live --> Decided: Result analysed
Decided --> Promoted: Winner becomes control
Decided --> Abandoned: No improvement
Promoted --> CleanedUp: Variations and code branches removed
Abandoned --> CleanedUp
CleanedUp --> [*]
| Stage | What happens | Who is responsible |
|---|---|---|
| Proposed | Hypothesis, metrics and duration written down | Product owner |
| Built | Feature created, code maps values to behaviour | Engineer |
| Testing | Verified in Development and Staging | Engineer and QA |
| Live | Weights set in Production, exposure logged | Engineer and analyst |
| Decided | Result analysed against the plan | Analyst and product owner |
| Promoted or abandoned | Winner becomes the permanent behaviour | Product owner |
| Cleaned up | Losing code and unused variations deleted | Engineer |
A scaffold goes up before building work, comes down when the building stands, and is hauled away. A scaffold left standing for years becomes a hazard and an eyesore. An experiment left running after its decision is the same: it costs attention and risks confusion.
The clean-up habit
When the winner is chosen, three things must follow. First, set the winning value as the control value. Second, remove the code branches that handled the losing variations. Third, delete the unused variations and, if the feature is no longer needed, the feature itself. Teams that skip this build up a pile of stale experiments that nobody dares to touch, which makes the code harder to read and increases the chance of accidents.
Each forgotten experiment is a tiny piece of debt. Put an end date in the description and have a weekly review list the ones past their date. Deleting is a feature, not a loss.
Making clean-up a team habit
Cleaning up is dull, so teams forget it. A few small rules help. Put the end date and owner in every feature description. Tag every experiment with the word “experiment”. Once a week, filter the feature list by that tag and read the end dates. Anything past its date gets a short message to its owner. When the owner confirms the decision, delete the variations, then the code branch, then the feature. Treat deletion as a normal, welcome task and celebrate the lighter codebase.
What can go wrong if you delete too early
If you delete a variation while some phones still hold an older cached answer, those phones may receive a label that your new code no longer knows. This is why the label-mapping habit with a control fallback matters: even stale answers cannot break the screen. Remove the code branch first in a release, wait until old app versions have mostly updated, then delete the feature in Flagsmith.
Weights to zero, then promote the winner, then release code without the losing branch, then wait for old app versions to fade, and only then delete the feature and variations.
21Performance, Caching and Resilience
Flags sit on the path of every page. They must be fast, and they must never be the reason a page fails.
Cache what you can
Fetching variations on every screen wastes time. SDKs generally keep results in memory, and many can store them on the device so the next launch starts instantly. Teams refresh in the background every so often and accept a few minutes of staleness in return for speed.
Always have a default
If Flagsmith cannot be reached, the SDK needs something to fall back on. Good applications supply a default value in code for each flag. For a multivariate feature the safe default is nearly always the control behaviour, which is the version already proven in production.
flowchart TD
A["App needs the value for identity I"] --> B{"Fresh cached value?"}
B -- Yes --> C["Use cached value"]
B -- No --> D["Ask Flagsmith with short timeout"]
D --> E{"Answer in time?"}
E -- Yes --> F["Use and cache it"]
E -- No --> G{"Older cached value?"}
G -- Yes --> H["Use older cached value"]
G -- No --> I["Use control behaviour from code"]
A driver checks live traffic. If the signal drops, the driver uses the last known route. With no history at all, the driver takes the normal main road. Each fallback is less clever but keeps the journey going.
Consistency during failures
A subtle risk: if the network fails and the app falls back to control while another device still shows a variation, the same person may see different versions on a single day. This is acceptable for a short outage but worth noting when you analyse results. Exposure logs should record what was actually shown, not what was meant to be shown.
Rules of thumb
- Never block the first paint of a page on a flag request for more than a moment.
- Read the value once and reuse it, rather than asking inside loops.
- Test what happens when Flagsmith is unreachable, in Staging, before an outage teaches the lesson.
- Make sure the control behaviour is always a fully working experience.
Choosing a timeout
A good timeout is short enough that a slow answer never freezes the page and long enough that normal answers arrive. Many teams start with a few hundred milliseconds for the first paint and a longer allowance for background refresh. Measure real response times before choosing, and revisit the number when networks or traffic change.
22Security and Privacy
Variations are visible to the devices that receive them. Treat everything in a variation as readable by a curious stranger.
Public keys, visible values
Client-side Environment keys are designed to be public, which means anyone who finds one can request values for any identifier they invent. They could therefore learn the names and values of your variations. Never place secrets, private addresses or confidential pricing rules inside a variation value or a feature name.
Flags are not permissions
A multivariate feature decides what to show, not what is allowed. If one variation unlocks a more powerful screen, the server must still check that the person is entitled to use it. Hiding a button is a convenience, not a lock.
| Risk | Example | Control |
|---|---|---|
| Values visible to clients | A hidden discount rule inside a variation | Keep rules on the server, send only labels |
| Feature names reveal plans | launch_secret_deal_2027 | Neutral, behaviour-based names |
| Flag used as a permission | Variation shows an admin screen | Server-side authorisation |
| Leaked server key | Key in a public repository | Secrets manager and rotation |
| Over-broad edit rights | Everyone can change Production weights | Groups, least privilege, audit log |
A restaurant can print different covers on its menus for a test without worry. It would never print the safe combination on them. Treat variation values as menu covers: fine to be seen, never to hold secrets.
Privacy of identifiers
Experiments depend on a steady identifier, and an identifier can be personal data if it can be linked to a person. Use opaque internal IDs rather than email addresses, record only what analysis needs, and remove old data when it is no longer required. Rules such as the European GDPR may apply, so involve your privacy team. This article is technical guidance, not legal advice.
Fairness and care
Experiments touch real people. Avoid testing changes that could harm, mislead or disadvantage a group, such as hiding important fees in one variation. A good question before any test is, “Would I be comfortable if every customer knew exactly what we were trying?”
A short privacy checklist
- Does the identifier avoid personal details such as an email address?
- Are exposure logs limited to what analysis needs?
- Is there a retention rule for old identities and logs?
- Can a person’s data be found and deleted on request?
- Has the privacy team reviewed the experiment if it touches sensitive areas?
23Monitoring, Audit and Debugging
When someone says “I see something different from my colleague”, good tools turn the puzzle into a short checklist.
The audit log
Flagsmith records changes: who edited a weight, added a variation or created an override, and when. A sudden change in results often matches an entry in the log, so checking it is the first move when numbers behave strangely.
The debugging checklist
Right Environment?
Production and Staging have different weights.
Right identifier?
Compare the exact text sent by the app, including capitals and spaces.
Any override?
An identity or segment override beats the weighted split.
Are weights what you think?
Read them again on screen, in the correct Environment.
Stale cache?
The app may still hold an older value.
Recent change?
Search the audit log around the time the problem began.
A detective asks the same questions each time: right place, right person, any special note, what do the records say, is the information old, and has anything changed lately. The checklist is that routine.
Signals worth watching
| Signal | What it tells you | Action if odd |
|---|---|---|
| Share of exposures per variation | Whether the split matches the weights | If far off, check the identifier and logging |
| Flag request latency | Whether Flagsmith calls are slow | Check caching and timeouts |
| Error rate | Reachability or key problems | Verify keys, defaults and status |
| Requests falling back to defaults | How often the safety net is used | Investigate outages |
| Guardrail metrics per variation | Harm in a variation | Reduce its weight quickly |
The sample ratio check
Analysts use a simple test called a sample ratio check. If the weights are fifty-fifty and the logged exposures are sixty-forty over thousands of people, something is wrong, for example a variation crashing for some devices so exposure is never logged. Catching this early protects the whole experiment from silent bias.
A debugging story
An analyst notices that the exposure logs show forty percent of people on control instead of the expected fifty. The sample ratio check has failed. The engineer opens the feature and finds the weights are correct. Then she looks at the logs by platform and sees that Android exposures for variation A are far below expectation. The cause: the Android build crashes on the screen for variation A for a small group of older phones, so no exposure is ever logged for them. Fixing the crash restores the expected ratio. Had nobody checked the ratio, the experiment would have wrongly concluded that variation A performed worse, because the struggling phones were quietly missing from its numbers.
Test identities
Keep a short list of named test identities for each variation, such as “test_variation_a” with an override pinning it to that version. Engineers and testers can sign in as these identities and see exactly what each version looks like on every device. Remember to leave these identities out of any analysis.
24Advantages, Disadvantages and Trade-offs
Multivariate features are powerful. An honest look at both sides helps teams use them wisely.
Evidence over opinion
Real customer behaviour settles arguments that meetings cannot.
Instant control
Change weights without a release, and reverse a bad change in seconds.
Steady assignment
The same person sees the same version, keeping data clean and customers calm.
One place to manage
Variations, weights and overrides live together instead of in scattered code.
Code complexity
Every variation is a branch in code that must be built, tested and later removed.
Statistical care
Splitting people is easy. Drawing correct conclusions needs discipline.
Small audiences
Many variations on little traffic give results too noisy to trust.
Experiment debt
Unfinished experiments pile up and confuse everyone.
| Trade-off | One side | Other side | Balanced approach |
|---|---|---|---|
| Speed versus safety | Even split learns fast | Small split protects customers | Start small, widen with confidence |
| Many ideas versus clear results | Many variations test more ideas | Few variations give clearer answers | Pre-filter ideas, test two or three |
| Freshness versus speed | Ask Flagsmith every time | Cache aggressively | Short cache with background refresh |
| Remote versus local evaluation | Rules stay on the server | Faster, fewer calls | Remote by default, local on hot paths |
A test kitchen can try many recipes, but each recipe costs ingredients and cooks’ time, and only a few tasters are available. A good chef chooses a short list of promising recipes, tests them properly and then retires the rest.
When not to use multivariate
If a change is obviously good, such as fixing a typo, simply release it. If a change is obviously needed for law or safety, release it without a test. If the audience is too small to measure any difference, a test only adds complexity. Use the tool where uncertainty is real and where the answer will change a decision.
25Design Patterns That Work
A pattern is a solution many teams have found useful again and again.
Pattern 1: Control plus one challenger
The simplest and often best design. One control, one variation, a fifty-fifty split. It gives the fastest and clearest answer, because each group is as large as it can be.
Pattern 2: Label-based variations
Make every variation a short name, and let the code map names to behaviour. Unknown names fall back to control. This keeps flags small, safe against typos and easy to review.
Pattern 3: Staff-first, then percentage
Pin a staff segment to the new variation so the team sees it first. Then give a small weight to everyone else, and grow it as confidence grows.
flowchart LR
A["Ring 1: staff pinned to new version"] --> B["Ring 2: 1 to 5 percent of customers"]
B --> C["Ring 3: 25 percent"]
C --> D["Ring 4: 50 percent, measure result"]
D --> E["Winner becomes control"]
Pattern 4: Holdback
After shipping a change to almost everyone, keep a small group, perhaps five percent, on the old behaviour for a few weeks. Comparing them later reveals long-term effects that a short test cannot see, such as customers returning less often after a novelty wears off.
Pattern 5: Guardrails with automatic stops
Link important guardrail metrics, such as error rate, to an alert that tells a human, or a carefully tested script, to set the variation weight to zero. A good test can end itself safely.
Pattern 6: One decision owner
Every multivariate feature has a named person who decides when the experiment stops, which variation wins and who cleans up. Without one, experiments drift on forever.
| Pattern | Problem it solves | Flagsmith tools used |
|---|---|---|
| Control plus challenger | Clear, fast answer | One variation, even weights |
| Label-based variations | Typos and messy code | Short values, code mapping |
| Staff-first, then percentage | Safe exposure | Segment override, weights |
| Holdback | Long-term effects | Variation at ninety-five percent |
| Guardrails with stops | Silent harm | Weights, API, alerts |
| One decision owner | Experiment drift | Feature description, tags |
These patterns are habits of a careful chef: taste a new sauce yourself, offer it to staff, then to a few regulars, keep a few old-recipe plates for comparison, and write who decides when it joins the menu.
Pattern 7: The decision record
When an experiment ends, write a short note in a shared place: the hypothesis, the dates, the weights, the number of people in each group, the main result, the guardrail result and the decision. Keep it brief, but keep it. Months later, when someone proposes the same idea again, the note saves weeks of repeated work and prevents repeated mistakes.
Pattern 8: Shared vocabulary of labels
Agree on naming rules for labels, for example “layout_grid” or “label_add_to_basket”, using lowercase words and underscores. When every team uses the same style, reports are easier to read and mistakes are easier to spot. A short naming guide pinned in the team wiki is enough.
26Anti-Patterns to Avoid
An anti-pattern looks like a good idea and causes pain later.
Changing weights constantly
Every change moves people between versions and muddies the data.
Too many variations
Eight versions on little traffic produce noise, not insight.
Session ID as identifier
Every visit reshuffles the person, so nobody sees a steady version.
Stopping when it looks good
Peeking and stopping early produces false wins.
Secrets in values
Client-readable values must never hold secrets.
Never cleaning up
Dead variations and code branches pile up as debt.
| Anti-pattern | Symptom | Remedy |
|---|---|---|
| Editing the variation text mid-test | Results cannot be compared | Create a new variation or a new experiment |
| Different identifiers in web and mobile | One person sees two versions | Agree on one identifier |
| No exposure logging | Behaviour cannot be linked to version | Log at the point of display |
| Control not a safe, working experience | Outage falls back to a broken page | Keep control fully functional |
| Overrides left on forever | A few customers never see the experiment | Expiry reminders for pinned identities |
| Testing too many things at once | Effects tangled together | One change per experiment, or planned interaction tests |
Changing the recipe halfway through a baking contest means the judges are no longer tasting the same cake. A fair contest fixes the recipes first and judges them at the end.
The tempting shortcut
The most tempting anti-pattern is to run an experiment and quietly keep adjusting it until the result looks good. Each adjustment feels small, but together they make the result unreliable. If you want to learn something different, start a new experiment with a new plan. Honest records are worth more than flattering numbers.
27Best Practices and Common Mistakes
Habits that keep multivariate work healthy, and the mistakes teams make without them.
Best practices
Write the hypothesis first
One sentence, one metric, one planned end date.
Use short labels as values
The code maps labels to behaviour, with control as the fallback.
Choose a stable identifier
Internal user ID, or a stored device ID before sign-in.
Log exposure once, at display
Include the feature, variation and identifier.
Keep weights steady during measurement
If you must change them, note the date and treat it as a new period.
Rehearse in lower Environments
Test each variation, the fallback and the outage case.
Watch guardrails
Errors, speed and complaints for every variation.
Clean up promptly
Promote the winner, delete the rest, remove code branches.
Common mistakes
| Mistake | Why it happens | Prevention |
|---|---|---|
| Editing the wrong Environment | Top bar not checked | Confirm the name before each change |
| Expecting weight changes to apply instantly everywhere | Caches hold old answers | Know your cache time |
| Weights adding to more than one hundred | Typing mistakes | Re-read the summary after editing |
| Forgetting that overrides beat weights | They are invisible in daily use | Check effective value for a test identity |
| Calling the winner too soon | Excitement and pressure | Agree the stopping rule beforehand |
| Using multivariate when a segment would do | It feels sophisticated | Ask whether you can describe the group |
If a new teammate cannot explain in one minute why a given customer sees a given version, the setup has become too complicated. Simplify before adding anything new.
Teach the habits
Good habits spread when they are written down and practised. Hold a short walkthrough for every new engineer and product manager using a harmless sample feature in Development. Let them create variations, set weights, open a test identity and read the effective value. Twenty minutes of practice removes most of the fear and prevents the common mistakes described above.
28Real-World Scenarios
Imaginary but realistic stories show how the pieces fit. The companies are invented for illustration.
Scenario 1: The online bookstore
PageTurn, a fictional bookstore, wants more people to finish checkout. The team creates a multivariate feature called checkout_button_label with control “Buy now” and variations “label_add_to_basket” and “label_get_it_today”. Staff are pinned to the new labels by a segment. In Production the two variations each get twenty-five percent, leaving fifty percent on control. The code maps the labels to text and falls back to “Buy now” for anything unknown. Exposure is logged when the button appears. After three weeks, “Get it today” shows a modest improvement without more complaints. The team sets it as the control value, deletes the other variation and removes the old code branch.
Scenario 2: The streaming service
StreamNest, a fictional video service, tests three home screen layouts: list, grid and cards. Because traffic is large, a three-way split is possible. The identifier is the internal user ID, so each viewer keeps the same layout on phone and television. Guardrails include time to first play and error rate. The cards layout slows older televisions, so its weight is reduced to zero within hours, and the other two continue.
Scenario 3: The travel booking site
RoamEasy, a fictional travel site, is moving its search to a new engine. A feature with variations “engine_old”, “engine_new” begins at one percent for new engine, grows to five, twenty-five, then fifty. At twenty-five a spike in slow queries appears. The team sets the weight to zero, fixes an index, and resumes the ramp the next week. Customers barely notice, because the old engine was always one weight change away.
Scenario 4: The business software vendor
LedgerLeaf, a fictional accounting product, wants to test a shorter onboarding flow. The experiment is limited to new accounts by a segment, and the identifier is the account ID so that everyone in one company sees the same flow. Strategic customers are pinned to control. After analysis, the shorter flow wins and is promoted.
| Scenario | Identifier | Variations | Key safeguard |
|---|---|---|---|
| Online bookstore | Internal user ID | Two labels plus control | Label mapping with control fallback |
| Streaming service | Internal user ID | Three layouts | Guardrail metrics and instant weight change |
| Travel booking | Device or user ID | Old and new engine | Gradual ramp, weight to zero |
| Business software | Account ID | Two onboarding flows | Segment targeting, strategic accounts pinned |
These stories are like different shops using the same cash register. The machine is identical, but each shop configures it for its own customers and its own level of care.
Lessons across all four
- A stable identifier was chosen first.
- Control was always a working, safe experience.
- Weights moved gradually, and a quick path back existed.
- Exposure and guardrails were measured.
- The winner was promoted and the rest was removed.
29Frequently Asked Questions
Short answers to common questions about multivariate features.
Is multivariate the same as A/B testing?
A/B testing compares two versions. Multivariate features in Flagsmith can serve two or more versions, so they support A/B and A/B/n tests. Flagsmith provides the splitting. Your analytics tool provides the measurement.
Do I need identities to use multivariate?
For a steady split, yes. Without an identifier, the person generally receives the control value.
Will the same person always see the same variation?
Yes, while the identifier, feature and weights stay unchanged. Changing weights can move some people.
What is the control value?
The ordinary value of the feature, used as the baseline and as the share left over after the variations take theirs.
Can weights add up to less than one hundred?
Yes. The remaining people receive the control value.
Can different Environments have different weights?
Yes. Variations are defined with the feature, but weights are chosen for each Environment.
Can I pin a person to one variation?
Yes, with an identity override, or a whole group with a segment override. Pinned people are no longer randomly assigned, so consider excluding them from analysis.
What if Flagsmith is unreachable?
The SDK uses a cached value if it has one, otherwise the default in your code. Make that default the control behaviour.
How many variations should I use?
As few as answer your question. Each extra variation divides the audience and slows learning.
Can I change a variation’s text during a test?
It is better not to. Doing so mixes two different treatments in one group. Create a new variation or a new experiment.
Does Flagsmith analyse the results?
Flagsmith decides who sees what. Analysis normally happens in your analytics tools. Check the current documentation for available integrations and any built-in reporting.
Is it safe to put values in variations?
Yes for presentation and tuning values. No for secrets, because client applications can read them.
Should I remove the feature after the test?
Usually yes. Promote the winner, remove unused variations and code branches, and delete the feature if it is no longer needed.
Where can I find exact, current details?
The official Flagsmith documentation. SDK methods, limits, permission names and bucketing details can change between releases.
A short glossary to keep nearby
| Word | Plain meaning |
|---|---|
| Multivariate feature | One feature carrying several possible values shared out by weight |
| Control value | The baseline value of the feature |
| Variation | An alternative value given to a share of people |
| Weight | The percentage of people receiving a variation |
| Bucket | A steady number from a hash, used to choose a variation |
| Identity | One end user, account or device known to Flagsmith |
| Override | A special answer for a person or group that beats the weighted split |
| Exposure | The moment a person actually sees a variation |
| Guardrail | A safety metric watched to catch harm |
| Canary release | A small first exposure used to find trouble early |
30Summary and Key Takeaways
A final walk through the essentials, in plain words.
A multivariate feature in Flagsmith is one feature that carries several possible values, called variations, with a control value as the baseline. Each variation has a weight, the percentage of people who receive it, and weights are set separately for each Environment. For each person, Flagsmith turns the identifier and the feature into a steady bucket number, finds which variation owns that bucket and returns its value, so the same person sees the same version every time. Identity overrides and segment overrides come first, and only people with no override are shared out by weight.
The craft lies around the mechanism. Write a hypothesis, choose one main metric and a few guardrails, keep weights steady while measuring, record exposure at the moment of display, and keep the control behaviour safe and working. Keep values short and free of secrets, enforce real permissions on the server, and clean up once a decision is made.
- A multivariate feature is one feature with a control value plus weighted variations, so one question gets one of several answers.
- Flagsmith hashes a stable identifier into a bucket, so the same person keeps the same version while weights stay unchanged.
- Overrides beat weights: identity first, segment second, weighted split last. Pinned people are not randomly assigned.
- Weights belong to each Environment, so you can test widely in Development and cautiously in Production.
- Good experiments need a hypothesis, a steady identifier, exposure logging, guardrails and a rule for when to stop.
- Keep control safe, keep secrets out of values, and promote the winner then delete the rest.