Identity in Flagsmith
How a feature flag learns who is asking. Discover what an identity is, how it is created, what traits and overrides add to it, and how to design identities that make rollouts precise, experiments fair and privacy safe.
Imagine a coffee shop that wants to try a new loyalty offer. If the shop treated every customer as a stranger, the only choice would be to give the offer to everybody or to nobody. But a shop that recognises its regulars can say, “Priya, our long-time customer, gets the offer first. The student who visits on Fridays gets a different one. The tourist passing through gets neither.” The shop is not being unkind. It simply knows who it is talking to.
Feature flags work in exactly the same way. A flag with no knowledge of the person is a blunt tool: it is on for all or off for all. The moment a flag learns who is asking, it becomes precise. It can open a feature to ten percent of customers, to staff only, to one troublesome account, or to everyone except a country where the law differs. In Flagsmith, that knowledge arrives through a small but powerful idea called an identity.
This guide explains identity from the very beginning, with no prior knowledge needed. Every new word is explained when it first appears, and every idea comes with a picture from everyday life.
1What Is an Identity in Flagsmith?
Before identity makes sense, three small ideas need a clear definition: the feature flag, the platform, and the question of who is asking.
The feature flag
A feature flag (also called a feature toggle) is a switch placed inside software that decides whether a behaviour is active. The code for a new feature is already deployed, and the flag decides whether users can reach it. Change the flag and the behaviour changes, with no new release.
The platform
Flagsmith is a feature flag and remote configuration service. It offers a dashboard where people manage flags, and small libraries called SDKs that applications install so they can ask, “what should this flag be right now?” It is open source, can be run by a company on its own servers, and is also offered as a hosted service.
The identity
An identity is Flagsmith’s name for one end user, account or device that your application tells it about. It is represented by a single piece of text called the identifier, usually a user ID such as “user_48213”. When the application asks for flags for an identity, Flagsmith can work out an answer tailored to that specific person, based on the facts it knows about them and the rules your team has written.
An identity can carry traits, which are facts such as “plan equals premium” or “country equals India”. It can also carry overrides, which are special answers for that one person. Together, these are what let Flagsmith say yes to one customer and no to the next.
An identity is a library membership card. The card number is the identifier. The card may have notes on it, such as “student” or “has a project loan”, which are traits. The librarian may also have a special instruction for that one card, which is an override. Without the card, you are served as an anonymous visitor under the general rules. With it, you are served as yourself.
In Flagsmith, “identity” means the people who use your product. It does not mean the colleagues who log in to the Flagsmith dashboard. Those are called members. The next chapters keep the two apart.
2Why Flags Need to Know Who Is Asking
A flag that treats everyone the same is useful. A flag that can tell people apart is transformative.
The problem identity solves
Without identity, every flag answer is the same for every visitor in an Environment. That is fine for a site-wide maintenance banner. It is hopeless for most real needs. A team cannot say “release this to ten percent of customers”, because the flag does not know who is who. A team cannot say “give this tool to paying customers only”. A team cannot say “turn this off for the one partner whose old system cannot cope”. Identity is the missing ingredient in all these sentences.
Gradual release
Show a feature to one percent, then ten, then everyone, with each person staying in the same group.
Plans and pilots
Give a capability to paying customers, staff or a loyal pilot group, and nobody else.
Fair comparisons
Split people between versions of a screen so a team can measure which works better.
One-off fixes
Turn a feature on or off for a single customer who is having trouble, without touching anyone else.
A cinema that cannot tell customers apart must charge everyone the same price. A cinema that can see a student card, a senior pass or a staff badge can offer different prices fairly and safely. Identity is the card that lets your product do the same with features.
What large companies teach us
Companies known for running large online experiments, such as Netflix, Google and Facebook, have written publicly about the need to assign each person consistently to the same version of a product. If a viewer saw one design on Monday and a different design on Tuesday, the measurements would be meaningless and the experience confusing. Consistent assignment requires a stable notion of who a person is, and that is precisely what an identity provides.
3Where Identity Sits in the Flagsmith Tree
Flagsmith is built as a tree. Locating identity in that tree explains why identities behave the way they do.
At the top is the Organisation, which holds people, groups and billing. Below it are Projects, one for each product. Beneath each Project are Environments, such as Development, Staging and Production. Identities live inside an Environment. That detail is important: an identity called “user_48213” in Production is a completely separate record from “user_48213” in Staging.
graph TD
ORG["Organisation: Acme Corp"] --> PRJ["Project: Store"]
PRJ --> FEAT["Features and Segments defined once"]
PRJ --> DEV["Environment: Development"]
PRJ --> STG["Environment: Staging"]
PRJ --> PRD["Environment: Production"]
PRD --> I1["Identity: user_48213"]
PRD --> I2["Identity: user_90417"]
I1 --> T1["Traits: plan = premium, country = India"]
I1 --> O1["Overrides: checkout_new_payment_sheet = on"]
I2 --> T2["Traits: plan = free, country = Germany"]
| Item | Lives at | Shared across Environments? | Example |
|---|---|---|---|
| Feature definition | Project | Yes | checkout_new_payment_sheet |
| Segment definition | Project | Yes | Premium customers |
| Feature state | Environment | No | On in Development, off in Production |
| Identity | Environment | No | user_48213 in Production |
| Trait | Identity | No | plan = premium |
| Identity override | Identity | No | On for this one person |
Because identities are per Environment, an override you set for a person in Staging does nothing in Production. If a customer-specific fix is needed in the live product, make it in the Production Environment, using the Production key and the Production identity.
A hotel chain keeps one list of room types and one list of rules, but each branch keeps its own guest register. A guest named Priya at the Delhi branch is not automatically on the register at the Mumbai branch. Environments keep separate guest registers in the same way.
4Identity Versus Member Versus Anonymous Visitor
Three similar-sounding ideas live in Flagsmith conversations. Keeping them apart prevents a great deal of confusion.
The member
A member (also called a user of the dashboard) is a colleague who logs in to the Flagsmith dashboard to manage flags. Members belong to an Organisation, are placed in groups and are given permissions. They are the people who use Flagsmith.
The identity
An identity is an end user of your product, such as a shopper, a driver or a patient. It exists inside an Environment and is created because your application tells Flagsmith about it. Identities are the people who use what you build.
The anonymous visitor
An anonymous visitor is someone who uses your product without being known, for example before signing in. If the application does not supply an identifier, Flagsmith has no identity to work with, so only the Environment’s general rules can apply.
| Concept | Who it is | Where it lives | Managed by |
|---|---|---|---|
| Member | A colleague using the dashboard | The Organisation | Administrators, through groups and roles |
| Identity | A customer or device using your product | An Environment | Your application, through the SDK |
| Anonymous visitor | Someone not yet known | Nowhere in Flagsmith | Nobody, receives the Environment default |
In a theatre, the staff who run the box office and lights are the members. The people with tickets in the audience are the identities. Someone looking through the window without a ticket is the anonymous visitor. The staff decide what the show allows, but the audience is who the show is for.
When a teammate says “can you give Priya access?”, ask which Priya. A colleague who needs dashboard access is a member. A customer who needs a feature unlocked is an identity. The actions and the permissions involved are completely different.
5The Identifier: Choosing a Good One
The identifier is the single most important decision in an identity design. A good one lasts for years. A bad one causes quiet trouble for just as long.
What the identifier is
The identifier is the text that names an identity. Flagsmith treats it as a label. If your application sends the same identifier again, Flagsmith recognises the same identity, with all its traits and overrides. If it sends a new identifier, Flagsmith sees a brand new person.
Rules for a good identifier
Stable
It must not change when a person changes their email, their name or their phone. An internal user ID that never changes is ideal.
Unique
Two different people must never share an identifier, or they will share traits and overrides too.
Private
It should not reveal personal facts. An opaque ID is better than an email address or a phone number.
Consistent in format
Agree on one style, including capital letters, and always send it the same way. “User_1” and “user_1” may be treated as different.
Available everywhere
The web app, the mobile app and the server should all be able to produce the same identifier for the same person.
| Candidate | Stable? | Private? | Verdict |
|---|---|---|---|
| Internal user ID, such as user_48213 | Yes | Yes | Best choice |
| Email address | No, people change it | No, it is personal data | Avoid |
| Phone number | Not always | No | Avoid |
| Random device ID created at install | Stable for that install only | Yes | Fine for anonymous visitors |
| Session ID | No, changes every visit | Yes | Avoid, it breaks consistent rollouts |
| Company or account ID | Yes | Yes | Excellent for company-level flags |
A passport number outlives changes of address, name and hairstyle, which is why governments rely on it. A person’s address, by contrast, changes whenever they move. Choose an identifier that behaves like the passport number, not like the home address.
If you change the format of identifiers after launch, for instance from email addresses to user IDs, every person looks like a new person. Their overrides vanish, their traits start empty, and their position in any percentage rollout is reshuffled. Decide carefully on day one.
A naming walkthrough
Suppose a company called Brightleaf runs a web app, an Android app and a billing service. The web app knows people by a database number, the Android app knows them by a login token, and the billing service knows them by a customer code. If each system sent its own label to Flagsmith, one human would become three identities, and a segment built on one label would miss the other two. The cure is to agree on one shared label, the internal user ID, and make every system translate its own label into it before talking to Flagsmith.
The translation step is small but important. In the web app it may be a simple lookup in the session. In the Android app it may be a field returned by the sign-in call. In the billing service it may be a column in a table. Write the rule down in one sentence, “Flagsmith identifiers are always the internal user ID in lowercase”, and place that sentence where every engineer will find it.
Case and spacing
Computers are literal. “User_48213”, “user_48213” and “user_48213 ” with a trailing space are three different pieces of text. Many bugs that look mysterious are just one of these. Trim spaces, pick one case, and apply the same normalisation in every application. A small shared helper that cleans the identifier before it is sent removes a whole class of surprises.
Copy an identifier from your logs and search for it in the dashboard. If the search finds nothing but the person is certainly active, compare the text character by character. The difference is usually a capital letter or a space.
6The Anatomy of an Identity
Open an identity in the dashboard and you will find a handful of parts. Knowing them makes the screen easy to read.
Identifier
The text that names the person or account, such as “user_48213”. It is how your application and Flagsmith agree on who is who.
Traits
Key and value pairs such as plan equals premium. Segments read these to decide who belongs to a group.
Overrides
Special answers for this one person, such as a feature switched on regardless of segments.
Effective flags
The final answer for every feature after all rules are applied. This is what the application actually receives.
Reading the effective flags
The most useful part of an identity page is the list of effective flags: for each feature, what this person receives and why. A row might say that a feature is on for this person because of a segment called “Premium customers”, or because of an identity override, or because of the Environment default. This explanation turns a mysterious complaint, such as “the new page does not show for me”, into a ten second lookup.
| Feature | Effective answer | Reason shown |
|---|---|---|
| checkout_new_payment_sheet | On | Identity override |
| reports_enable_advanced_export | On | Segment: Premium customers |
| search_results_per_page | 20 | Environment default |
| home_show_legacy_banner | Off | Environment default |
A passport control officer sees your passport, any visa stamps and any special notes, and then says “enter” or “wait here”. The officer can also tell you why. The identity page is that officer’s screen, showing both the decision and the reasons.
Because this page shows the answer and the reason together, it is the first place support engineers and developers look when a person reports surprising behaviour. Later chapters return to it as a debugging tool.
7Traits: The Facts That Describe an Identity
An identifier says who a person is. Traits say what that person is like. Together they let flags make smart decisions.
What a trait is
A trait is a single fact about an identity, stored as a pair: a key (the name of the fact) and a value (the fact itself). For example, the key “plan” might have the value “premium”, and the key “country” might have the value “India”. A single identity can hold many traits at once.
Why traits matter
Traits are the raw material for segments. A segment is a saved group definition such as “all customers whose plan equals premium”. Flagsmith checks the traits of each identity against the segment rules to decide who is inside the group. Without traits, segments would have nothing to look at.
Think of the name tag at a conference. The name is the identifier. The coloured stickers on the tag, such as “speaker”, “vegetarian” and “workshop B”, are traits. Organisers do not need to know your life story. They glance at the stickers and decide which door to point you towards.
Kinds of values
| Kind of value | Example key and value | Typical use in a segment |
|---|---|---|
| Text | plan = premium | Equals, not equals, contains |
| Number | orders_last_year = 12 | Greater than, less than |
| True or false | is_beta_tester = true | Equals true |
| Version-like text | app_version = 4.2.1 | Version comparison, where supported |
Where traits come from
Traits can arrive in three ways. First, the application can send them along when it asks for flags, which is the most common and the freshest path. Second, the application can save them through a separate call so they are stored for later. Third, a team member can type them into the dashboard, which is handy for testing. Check the current documentation for the exact methods each SDK offers.
Sent with the request
The app includes the traits as it asks for flags. Flagsmith can use them immediately and store them for next time.
Saved separately
The app updates a trait when something changes, such as a plan upgrade, without needing a flag request at that moment.
Typed in the dashboard
A teammate adds a trait by hand to reproduce an issue or to test a segment.
Choose names that read like plain facts: “plan”, “country”, “signup_month”. Use lowercase and underscores, and keep the same spelling in every application. A typo such as “contry” quietly creates a second, useless trait.
Traits are claims, not proofs
Flagsmith trusts what the application tells it. If a browser app sends “plan = premium”, Flagsmith has no way to verify that the person really paid. This is perfectly fine for choosing which feature to show. It is not fine for protecting something valuable. Feature flags decide what to display or enable. Real permission checks must still happen on the server that owns the data. Chapter 22 returns to this idea in detail.
8How an Identity Is Born
Nobody has to fill in a form to create an identity. Flagsmith makes one the first time it hears the identifier.
Creation on first contact
When an application asks Flagsmith for flags for an identifier it has never seen, Flagsmith creates the identity at that moment, stores any traits that came with the request, and returns the answer. No pre-registration is needed. This lazy style of creation keeps integration simple: the app just says who it is and gets flags back.
The person signs in
Your application now knows a stable ID for the person, such as user_48213.
The app asks for flags
It calls the SDK, passing the identifier and, optionally, a few traits.
Flagsmith looks for the identity
It checks the Environment for that identifier. If none exists, it creates one.
Traits are stored
Any traits in the request are saved on the identity, replacing older values for the same keys.
Flags are evaluated
Overrides, segments and defaults are applied, and the final list is returned.
A gym that issues a membership card the first time you walk in and scan your fingerprint does not need an appointment. The card appears when you show up. Flagsmith treats a new identifier the same way: first visit, instant membership.
Creation without a visit
A team member can also create an identity in the dashboard by typing an identifier. This is useful when a support engineer wants to prepare an override for a customer before the customer has ever opened the new feature. When that customer later arrives with the same identifier, the prepared override is already waiting.
Consequences of lazy creation
- A mistyped identifier does not cause an error. It simply creates a second identity.
- Identities accumulate over time, because creation is automatic and removal is not.
- Test code that uses random identifiers can fill an Environment with junk records.
Automated tests that generate a new identifier on every run can create thousands of throwaway identities. Point tests at a dedicated Development Environment, reuse a small set of test identifiers, and clean up periodically.
9The Journey of One Request
Follow a single request from the app to Flagsmith and back, and the whole system becomes easy to picture.
The cast of characters
Four actors take part. The application is your product. The SDK is a small library inside the application that knows how to talk to Flagsmith. The Flagsmith API is the server side service that answers. The rules store is where features, segments, overrides and identities are kept.
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 app and signs in
A->>S: Get flags for user_48213 with traits
S->>F: Request with Environment key, identifier, traits
F->>R: Find or create identity, save traits
R-->>F: Identity, overrides, segments, defaults
F->>F: Evaluate each feature in order
F-->>S: List of flags with values
S-->>A: Flags ready to read
A-->>U: Shows the right experience
Reading the diagram
The person signs in, and the application calls the SDK with the identifier. The SDK adds the Environment key, which tells Flagsmith which Environment the question concerns, and sends the request. Flagsmith finds or creates the identity, saves traits, collects every rule that applies, and evaluates each feature one by one. The finished list travels back to the application, which uses it to decide what to show.
This is like asking a hotel receptionist, “what is available for me?” The receptionist checks your booking, your loyalty tier and today’s offers, and hands you a personalised list. You never see the filing cabinet; you only see the answer.
Why this design is fast enough
Flags are small pieces of data, so a single response is tiny. SDKs usually keep results in memory so the application can read flags many times without asking again. Some SDKs can also refresh results in the background. Because the heavy work happens once per request rather than once per flag check, the cost stays low even for busy applications.
What the response contains
The answer that comes back is a list. Each entry names a feature, says whether it is enabled and, for features that carry a value, includes that value. The list holds only the answers for the one identity that asked. It does not contain other people’s data, the full list of segments or the rules behind the decisions. This keeps responses small and avoids revealing more than necessary to the device.
Think of the list as a menu card printed for one guest. The kitchen has many recipes and many rules about allergies, but the guest sees only the dishes they may order.
10The Order of Decisions
Several rules can apply to one person at once. Flagsmith resolves the conflict with a fixed order of priority.
Three layers of answer
For every feature, Flagsmith considers three layers, from most specific to most general. The identity override is a special answer for one person. The segment override is a special answer for a group. The Environment default is the general answer for everyone else. The first layer that applies wins, and the later layers are not consulted.
flowchart TD
A["Request for feature X for identity I"] --> B{"Does I have an identity override for X?"}
B -- Yes --> C["Use the identity override"]
B -- No --> D{"Does I belong to a segment that overrides X?"}
D -- Yes --> E["Use the segment override, highest priority segment wins"]
D -- No --> F["Use the Environment default for X"]
C --> G["Return value to the application"]
E --> G
F --> G
In a school, a note from a parent for one child outranks the class rule, and the class rule outranks the general school rule. The nearest, most specific instruction wins. Flagsmith applies the same common sense.
A worked example
Take a feature called “checkout_new_payment_sheet”. The Environment default is off. A segment called “Premium customers” turns it on. A particular customer, Anil, has an identity override that turns it off because he reported a problem with it.
| Person | Identity override? | In Premium segment? | Result | Deciding layer |
|---|---|---|---|---|
| Anil | Yes, off | Yes | Off | Identity override |
| Bela | No | Yes | On | Segment override |
| Chen | No | No | Off | Environment default |
| Dana | Yes, on | No | On | Identity override |
Anil is in the premium group, which would normally switch the feature on, yet his personal override says off, so he gets off. Dana is not premium, but her personal override says on. The person-level instruction always beats the group-level one.
When several segments apply
A person can belong to more than one segment, and two segments may disagree about the same feature. Flagsmith resolves this with segment priority: segments are ordered, and the one with the highest priority supplies the answer. Teams should review that order whenever they add a new segment override, because a high priority segment can silently win over a more specific one lower down.
A broad segment like “All customers” placed above a narrow segment like “Beta testers” will hide the narrow segment’s override for everyone. When a segment seems to be ignored, check the priority order before suspecting a bug.
Walking through the order with a story
Picture a school with three levels of instruction. The principal’s general rule says, “Phones are not allowed in class.” The class teacher’s rule for the science group says, “Phones are allowed for experiment photos.” A note from the nurse for one pupil says, “This pupil must keep a phone for a medical alert.” When that pupil is in the science group, the nurse’s note decides, because it is the most specific. When another science pupil enters, the class rule decides. When a pupil from another class enters, the principal’s rule decides. Flagsmith resolves feature answers in exactly this spirit.
What the application sees
The application never sees this ladder. It only receives the final answer: on or off, or a specific value. This is intentional. The rules can change on the dashboard without any change in the application, and the application does not need to know why a decision was made. The reason is visible to the team in the dashboard, which keeps the application simple and the reasoning inspectable.
Multivariate and remote config values
Not every flag is a simple on or off. Some carry a value, such as the number of search results per page, or a text such as a banner message. The same order applies to values: an identity override can set a different number for one person, a segment can set a different number for a group, and the Environment default supplies the number for everyone else. Some flags also split people between several named variants by percentage. Check the current documentation for the exact options your version supports.
| Flag kind | What an override sets | Example |
|---|---|---|
| On or off flag | Enabled or disabled for the person or group | New payment sheet on |
| Text value | A different message | Banner text for a pilot group |
| Number value | A different number | Search results per page set to 50 |
| Variant split | Share of people receiving each variant | Variant A 50 percent, variant B 50 percent |
11Identity Overrides in Depth
An identity override is the sharpest tool in the box. It deserves care, because sharp tools cut both ways.
What an override is
An identity override is a stored decision that says, “for this identity, feature X has this value, regardless of segments and defaults.” It can switch a boolean flag on or off, or set a specific value for a remote configuration value such as a text or a number.
Good reasons to use one
Fix one customer
A feature misbehaves for a single account. Turn it off for that identity while engineers investigate.
Trial a capability
A prospective client is allowed to test a premium feature for two weeks without a plan change.
Verify in production
A tester gets a feature in the live Environment before anyone else, to confirm it behaves correctly.
Dogfooding
Staff accounts get new features early, so the team uses what it builds before customers do.
Bad reasons to use one
Overrides are for exceptions. If a team finds itself adding the same override for fifty identities, that is a sign a segment is needed. If overrides are used to model permanent plan differences, they will become impossible to audit. Every override is a rule that only one person can see, so a pile of them hides the real logic of the product.
| Situation | Use identity override? | Better tool |
|---|---|---|
| One customer reports a bug | Yes | Identity override, with a note and an expiry reminder |
| Fifty pilot customers need early access | No | A segment based on a trait such as pilot = true |
| All paying customers get a feature | No | A segment based on plan |
| Ten percent of users should see a feature | No | A percentage split rule in a segment |
| QA tester needs a feature in production | Yes | Identity override, removed after testing |
A restaurant will happily make one special dish for one guest with an allergy. It will not rewrite the menu for each guest. Overrides are the special dish; segments are the menu sections.
The cleanup habit
An override created during an incident often outlives the incident. Months later nobody remembers why a certain customer sees different behaviour. Good teams treat overrides as temporary: they record the reason in a ticket, set a calendar reminder, and delete the override when the problem is solved. Reviewing the list of overrides during each release cycle keeps the system understandable.
12Segments Reading Identities
Segments are how identities are grouped. Understanding how a segment looks at an identity explains most real-world rollouts.
The segment in one sentence
A segment is a named set of rules that an identity either satisfies or does not. It is defined once in the Project and can be used in every Environment. When the application asks for flags, Flagsmith tests the identity against each segment and notes which ones it belongs to.
The building blocks of a rule
A segment rule has three parts: a trait name, an operator (the comparison), and a value. For instance, “plan equals premium” or “orders_last_year is greater than 10”. Several conditions can be joined with all (every one must be true) or any (at least one must be true).
| Operator idea | Plain meaning | Example |
|---|---|---|
| Equals | The trait has exactly this value | plan equals premium |
| Not equals | The trait has any other value | country not equals US |
| Contains | The text includes this piece | email contains @company.com |
| Greater or less than | Number comparison | orders_last_year greater than 10 |
| Is set or not set | The trait exists or does not | beta_invite is set |
| Percentage split | A stable slice of all identities | Include 10 percent |
flowchart LR
I["Identity user_48213"] --> T["Traits: plan = premium, country = India"]
T --> S1{"Segment: Premium customers, plan equals premium"}
T --> S2{"Segment: US only, country equals US"}
S1 -- Matches --> M1["Member of Premium customers"]
S2 -- Does not match --> M2["Not in US only"]
M1 --> F["Apply Premium segment overrides"]
A club has rules such as “members over sixty” and “members who joined before 2015”. Staff look at each member’s card and tick every group they belong to. Segments tick groups on each identity’s card in the same way.
Missing traits
If a segment rule needs a trait that the identity does not have, the rule normally does not match. This matters in practice: a person who has never been sent a “plan” trait will not be in the “Premium customers” segment, even if they have paid. The fix is to make the application send important traits consistently, every time it asks for flags.
Decide the small set of traits your segments will depend on, document them in one shared page, and make every application send them. Ten well-named traits serve better than fifty scattered ones.
13Percentage Rollouts and Stable Buckets
Rolling out to “ten percent of users” sounds simple. Doing it fairly and consistently is where identity earns its keep.
The goal
A percentage rollout releases a feature to a fraction of people, then grows that fraction over days. The key promise is consistency: a person who is in the ten percent today must still be in the group when it grows to twenty percent tomorrow. Nobody should see the feature appear, disappear and appear again.
How consistency is achieved
The usual technique is called hashing. A hash function turns any text into a long, scrambled number that always comes out the same for the same input. Flagsmith combines the identifier with other information, turns it into a number between zero and one hundred, and compares it with the chosen percentage. The same person always lands on the same number, so they stay in or out of the group predictably. Check the current documentation for the exact details of how Flagsmith builds this number.
Imagine giving every student a seat number based on their birthday letters, and then saying “seats one to ten get the new textbook today, seats one to twenty tomorrow.” Nobody changes seats overnight. Students who got the book yesterday keep it, and new students are simply added.
flowchart LR
A["Identifier: user_48213"] --> B["Hash function"]
B --> C["Stable number 0 to 100, e.g. 37"]
C --> D{"Is 37 below the rollout percentage?"}
D -- "Rollout 10%" --> E["Not in group"]
D -- "Rollout 50%" --> F["In group"]
| Day | Rollout | Person with number 37 | Person with number 8 |
|---|---|---|---|
| Monday | 10 percent | Not included | Included |
| Wednesday | 25 percent | Not included | Included |
| Friday | 50 percent | Included | Included |
| Next week | 100 percent | Included | Included |
What breaks consistency
- Changing identifiers. A session ID or random value changes every visit, so the person lands in a different bucket each time.
- Mixing formats. Sending “User_1” from one app and “user_1” from another gives two numbers for the same human.
- Anonymous visitors without a stored ID. If the app forgets the device ID, the person is reshuffled.
Hashing spreads people evenly over large numbers, but with only a few hundred users the actual share may be a little above or below the target. This is normal statistics, not a fault.
Why this matters for experiments
Teams that run experiments need each person to see one version only. Companies like Netflix and Google have described the importance of stable assignment in their public engineering writing. Without it, measurements are polluted: someone who sees both versions cannot tell you which was better. A stable identifier is the quiet foundation under every fair comparison.
Choosing rollout steps
Teams often pick steps such as one percent, five percent, twenty-five percent, fifty percent and one hundred percent. The first step is small enough that a mistake affects few people, yet large enough to produce real measurements. Between steps, the team watches error rates, speed and customer feedback. If anything looks wrong, they reduce the percentage or switch the feature off, and the same people who had it before lose it together, which makes the effect easy to understand.
A word about fairness
Hashing spreads people evenly with respect to their identifier, but identifiers may carry hidden patterns. If identifiers are numbers handed out in order, early customers have small numbers and late customers have large ones. A well designed hash scrambles these patterns so that the early and late customers mix, but it is still worth checking that the group who received the feature looks like your overall customer base before drawing strong conclusions from an experiment.
Combining a percentage with traits
A segment can combine conditions, for example “country equals India and a ten percent slice of identities”. This releases the feature to a tenth of customers in one country only. It is a useful way to test in a single market before a global launch. Because both conditions must be true, a person outside the country never receives the feature, whatever their bucket number is.
14SDKs, Keys and Who Can Ask
Identities are only useful if the right software can ask for them safely. Keys are the doors, and not all doors should be open to all people.
The Environment key
Every Environment has an Environment key. When an SDK sends a request, the key tells Flagsmith which Environment to use. Two kinds are commonly distinguished. A client-side key is designed to be placed inside web pages and mobile apps, where anyone can find it. A server-side key is meant to be kept secret on your own servers, and it can unlock extra powers such as downloading the whole Environment document for local evaluation.
| Key kind | Where it lives | Secret? | Typical use |
|---|---|---|---|
| Client-side Environment key | Browser or mobile app | No, it is public by design | Fetch flags for one identity |
| Server-side Environment key | Your backend servers | Yes | Fetch flags and, optionally, evaluate locally |
| Organisation API key | Admin scripts and automation | Yes | Manage flags, identities and settings programmatically |
A client-side key is like the public phone number of a shop: anyone can ring it and ask what is on the menu. A server-side key is like the staff door key: only trusted people should hold it. The Organisation key is the master key to the building.
Who asks in each setting
Browser app
Uses the client-side key. Asks for the signed-in person’s flags and traits.
Phone app
Uses the client-side key. Caches flags so the app works with weak networks.
Server code
Uses the server-side key. May evaluate flags for many different identities per second.
Admin scripts
Use the Organisation key to create identities, add overrides or audit settings.
What a client-side key can reveal
Because a client-side key lives in public code, anyone can copy it and ask Flagsmith for flags. A curious person could request flags for any identifier they invent and see the answers. This is why nothing secret or sensitive should be placed in flag values or traits. A flag called “enable_new_checkout” is harmless to expose. A flag value containing an internal URL, a password or a secret price rule is not. Chapter 22 expands on this.
15Remote Evaluation and Local Evaluation
There are two ways to decide what an identity should see: ask Flagsmith each time, or learn the rules and decide at home.
Remote evaluation
In remote evaluation, the SDK sends the identifier and traits to Flagsmith, and Flagsmith does the thinking. The rules never leave the server. This is the default and is simple and safe, because the application receives only the final answers for one person.
Local evaluation
In local evaluation, a server-side SDK downloads the whole Environment definition, including features, segments and identity overrides, and keeps it in memory. It then works out answers itself without a network call for each person. This can reduce delay and load when a backend serves many identities per second. The price is that the rules are held in your server, so the secret server-side key is required, and the copy of the rules is refreshed on a schedule and may be briefly out of date. Check the current documentation for which SDKs support this mode.
flowchart TD
subgraph R["Remote evaluation"]
A1["App"] -->|"identifier + traits"| B1["Flagsmith API"]
B1 -->|"final flag values"| A1
end
subgraph L["Local evaluation"]
B2["Flagsmith API"] -->|"Environment document, refreshed periodically"| A2["Server SDK memory"]
A2 --> C2["Evaluate for any identity locally"]
end
| Question | Remote evaluation | Local evaluation |
|---|---|---|
| Who decides? | Flagsmith server | Your own server |
| Network call per decision? | Yes, usually cached | No |
| Freshness of rules | Fresh at each request | As fresh as the last refresh |
| Where rules are visible | Only inside Flagsmith | In your server memory |
| Key needed | Client or server key | Server-side key |
| Best for | Web, mobile, simple servers | High-volume backends |
Remote evaluation is phoning head office each time a customer asks for a discount. Local evaluation is holding a printed rulebook at the counter, refreshed each morning. The phone call is always up to date but slow. The rulebook is instant but may miss a change made after breakfast.
Choosing between them
Start with remote evaluation. It is easier to reason about and keeps rules private. Switch a specific high-volume backend to local evaluation when measurements show that the network calls are a real cost, and when you accept the trade-off of slightly delayed rule changes.
Staleness in local evaluation
Because a server keeps its own copy of the rules, a change made in the dashboard takes a short while to reach it. During that window, the server may answer using the old rules. For most features this is harmless. For an emergency kill switch, a delay of even a minute may matter, so teams that depend on instant shutdown should measure the refresh interval, choose it deliberately, and test the switch before they need it.
It is also worth knowing that local evaluation only knows the traits you pass in the call. The server does not look up stored traits in the same way, so the application must supply the traits that matter for each decision. Check the current documentation for exactly how your SDK handles stored versus supplied traits.
16From Anonymous to Known
Every product has people who browse before signing in. Handling the moment they become known is one of the trickiest identity design problems.
The anonymous stage
Before sign-in, the application has no person ID. It can create a random device identifier on first visit, store it on the device, and use it as the Flagsmith identifier. The visitor then gets consistent behaviour across page loads, including a stable place in any percentage rollout.
The sign-in moment
When the person signs in, the application learns their real user ID. If it simply switches to the user ID, Flagsmith sees a brand new identity and the person might be reshuffled into a different bucket. Their experience may change mid-visit, which feels odd.
stateDiagram-v2
[*] --> Anonymous: First visit, device ID created
Anonymous --> Anonymous: Browsing, flags by device ID
Anonymous --> SignedIn: Signs in, user ID known
SignedIn --> SignedIn: Flags by user ID with traits
SignedIn --> Anonymous: Signs out, device ID again
Choices at the switch
| Strategy | How it works | Pros | Cons |
|---|---|---|---|
| Switch to the user ID | Use the device ID before sign-in, the user ID after | Simple, matches server records | Bucket may change at sign-in |
| Always use the device ID | Ignore the user ID entirely | No change at sign-in | Same person on two devices gets two experiences |
| Always require sign-in first | No anonymous stage | One identity per person | Not possible for public pages |
| Use the user ID for features, the device ID for experiments on public pages | Choose per flag type | Best of both | Needs careful design and documentation |
A visitor at a theme park gets a temporary wristband at the gate. If they later buy an annual pass, the staff must decide whether to swap the wristband for the pass or keep both. Doing it badly means the visitor is suddenly treated like a stranger halfway through the day.
For marketing pages and experiments that run before sign-in, a stored device ID is a fine identifier. For features inside the signed-in product, prefer the user ID. Keep the two clearly separate in your naming so nobody mixes them.
17Identity for Businesses: Users, Accounts and Teams
Many products sell to companies, not individuals. Then the question becomes: is the identity the person, or the company?
Two levels of “who”
In a business product, a user belongs to an account (also called a tenant, a company or a workspace). Some decisions apply to the whole account, such as “this company has bought the analytics module”. Others apply to the person, such as “this person is testing the new editor”.
Design choices
Identity is the user
Each person is an identity. Account facts, like account_id and account_plan, are stored as traits so segments can group by company.
Identity is the account
One identity per company. Everyone in the company gets the same flags. Simple, but per-person tests are impossible.
Both, in different Projects or flags
Account-level capability flags use account identities. Person-level experiments use user identities. Needs discipline to keep apart.
A gym membership can be individual or family. A family plan gives every family member the pool, but each person still has their own locker key. Business products often need both layers at once.
Why Option A is a common starting point
Storing the account ID as a trait on every user identity keeps flexibility. A segment can say “account_id equals acme_corp” to switch a feature on for all of one company’s staff, or “role equals admin” to target administrators only, or both together. Moving later from account identities to user identities is painful, whereas adding account traits to user identities is easy.
If a company has ten thousand staff, an override applied to all of them as individual identities means ten thousand records. Use an account trait and a segment instead, and keep identity overrides for single people.
| Need | Best approach |
|---|---|
| Unlock a module for one company | Segment on account_id or account_plan trait |
| Let one administrator test a feature | Identity override on that user |
| Roll out to ten percent of companies | Percentage split on an account-level identity or a stable account trait |
| Roll out to ten percent of people | Percentage split on user identities |
Roles inside an account
Within one company, people hold different roles: administrator, editor, viewer. A role trait lets segments target a feature to administrators only, which is common for settings and billing screens. Combine it with the account trait, and a segment can say “account_plan equals enterprise and role equals admin”. Only the right people at the right companies receive the feature. Remember that the role trait only controls what is shown. The server must still check that the person really is an administrator before allowing any change.
18Working With Identities in the Dashboard
The dashboard gives teammates a friendly window onto identities. Knowing what each screen offers saves hours of guessing.
The identities list
Inside an Environment, the identities page lists known identifiers. Teammates can search for a specific one, open it, create a new one or delete one. The list is a view of the Environment you are currently in, so always check which Environment is selected in the top bar before acting. Acting in Staging while believing you are in Production is one of the commonest mistakes.
The identity detail page
Opening one identity shows its traits, its overrides and its effective flags. From here a teammate can add or edit traits, switch a feature on or off for just this person, and see which segments the person belongs to.
Choose the right Environment
Confirm Production versus Staging before searching.
Search for the identifier
Paste the exact identifier from your own system, not an email or a name.
Read the effective flags
See each answer and the reason behind it.
Inspect traits and segments
Check whether the traits the segment needs are present and correctly spelled.
Decide whether to override
Only when it is a real one-off. Otherwise fix the segment or the trait.
This is the bank teller’s screen. The teller sees your account, your recent notes and any special instructions, and can add a note. The same teller would never change the bank’s overall rules from this screen, only your own file.
Permissions around identities
Not every member should be able to edit identities in Production. Flagsmith lets administrators grant permissions at the Environment level, so that, for example, developers may edit identities in Development and Staging but only a small group may do so in Production. Check the current documentation for the exact permission names, and follow the principle of least privilege: give people only what they need.
Bulk work and automation
When hundreds of identities need updating, clicking in the dashboard is slow and error prone. The Flagsmith API allows scripts to create identities, set traits and add overrides in bulk. Use the Organisation API key for such scripts, keep the key in a secrets manager, and log what the script changes so it can be reviewed later.
19The Lifecycle of an Identity
Identities are born, grow, change and eventually become stale. Planning for the whole lifecycle prevents clutter and privacy surprises.
stateDiagram-v2
[*] --> Created: First request with new identifier
Created --> Active: Traits stored, flags served
Active --> Active: Traits updated, overrides added or removed
Active --> Dormant: No requests for a long time
Dormant --> Active: Person returns
Dormant --> Deleted: Cleanup or privacy request
Deleted --> [*]
Stage by stage
| Stage | What happens | Team responsibility |
|---|---|---|
| Created | The first request with a new identifier makes the record | Make sure the identifier format is correct from the start |
| Active | Traits update, flags are served, overrides may be added | Keep traits fresh and overrides purposeful |
| Dormant | The person stops visiting | Decide how long to keep dormant records |
| Deleted | The record is removed | Do this for privacy requests and cleanup |
A library card is issued, used, left in a drawer for years and finally cancelled. A good library has a policy for the last step, so the records do not pile up forever and people can ask to be removed.
Why cleanup matters
Unused identities slow dashboards, make search results noisy and, more importantly, keep personal data longer than needed. Many privacy laws, such as the European GDPR, expect organisations to keep personal data only as long as there is a reason. Even an identifier like a user ID can be personal data if it can be linked back to a person. A cleanup routine, and a process to delete an identity when a person asks, protects both the customer and the company.
When a person asks to be forgotten
- Look up the identifier used for that person in every Environment.
- Delete the identity in each Environment where it exists.
- Remove the identifier from any exports, scripts or tickets you control.
- Record that the request was completed, without recording the personal details.
Ask your legal and privacy teams for the exact process your company must follow. This article is technical guidance, not legal advice.
20Traits Over Time: Freshness and Drift
A trait is only as good as its last update. Stale traits make segments quietly wrong.
The drift problem
Suppose the application sets “plan = premium” when a person subscribes. A year later the person cancels, but no code updates the trait. Flagsmith keeps believing the person is premium, and the premium features keep switching on. This silent mismatch is called drift: the stored fact drifts away from reality.
Strategies to prevent drift
Send traits on every request
The application includes current traits each time it asks for flags. Flagsmith always has the latest.
Update on events
When billing changes, a webhook or event handler immediately updates the trait.
Periodic reconciliation
A nightly job compares your database with Flagsmith traits and fixes differences.
Prefer fewer traits
Every trait is a promise to keep it correct. Store only what segments truly need.
A sticker on a suitcase saying “fragile” is useful only while the contents are fragile. If the owner empties the case and fills it with books but forgets to peel the sticker, handlers will keep treating it gently for no reason. Traits are stickers: peel them when they are no longer true.
Which traits drift fastest
| Trait | Changes how often? | Drift risk | Advice |
|---|---|---|---|
| country | Rarely | Low | Send on sign-in |
| plan | Occasionally | Medium | Update on billing events and send on requests |
| orders_last_year | Constantly | High | Send fresh on each request or recompute nightly |
| is_beta_tester | Rarely, by choice | Low | Set once, remove when programme ends |
| app_version | With each release | High | Always send from the app itself |
Treat your own database as the source of truth, and treat Flagsmith traits as a copy. Whenever the copy and the original disagree, the original wins and the copy must be fixed.
Ownership of traits
Every trait should have an owner: a team responsible for its meaning and its accuracy. Without an owner, nobody notices when a trait stops being sent, or when two teams begin to use the same name for different things. In the trait dictionary, write the owner, the system that supplies the value, how often it changes and which segments depend on it. When a team wishes to retire a trait, the dictionary tells them exactly which segments to update first.
A final good habit is to version traits when their meaning changes. If “plan” used to have values like “basic” and “pro” and now has “starter”, “team” and “enterprise”, create a new trait name such as “plan_v2” and migrate segments gradually. Silently changing the meaning of an existing trait is one of the hardest sources of bugs to find.
21Performance, Caching and Resilience
Flags sit on the critical path of your product. They must be fast and they must never be the reason a page fails.
Cache what you can
Fetching flags on every screen would waste time. Most SDKs keep the last result in memory, and many can store it on the device so that the next launch starts instantly. Teams usually refresh in the background every so often, trading a few minutes of freshness for a faster, cheaper product.
Always have a default
If Flagsmith cannot be reached, because of a network problem or an outage, the SDK needs something to fall back on. Good applications provide default values in code, the safe behaviour to use when no answer arrives. For a risky new feature, the safe default is usually off. For an old feature that must stay available, the safe default may be on.
flowchart TD
A["App needs a flag for identity I"] --> B{"Fresh cached answer?"}
B -- Yes --> C["Use cached answer"]
B -- No --> D["Ask Flagsmith"]
D --> E{"Answer received in time?"}
E -- Yes --> F["Use and cache the answer"]
E -- No --> G{"Older cached answer exists?"}
G -- Yes --> H["Use older cached answer"]
G -- No --> I["Use safe default in code"]
A driver planning a route checks the live traffic app. If the signal drops, the driver uses the last known route. If there is no last route, the driver follows the normal road. Each fallback is slower in accuracy but keeps the journey going.
Timeouts
A slow answer is almost as bad as no answer. Set a short timeout on the flag request, so a stalled network never freezes your page. If the timeout fires, use the cache or default and try again later.
Resilience rules of thumb
- Never let a flag request block the first paint of a page for longer than a moment.
- Choose the default for each flag deliberately and write it down.
- Test what happens when Flagsmith is unreachable. Do this in Staging before an outage teaches the lesson.
- Do not call Flagsmith inside tight loops. Read flags once and reuse the result.
Scale considerations
When thousands of identities ask at once, for instance at the start of a big sale, the combined load matters. Caching on the device, background refresh rather than refresh on every screen, and local evaluation for backends all reduce load. Ask your Flagsmith provider or your own operations team about rate limits and capacity, because these details change over time.
22Security and Privacy of Identities
Identities hold information about real people. Treat them with the care you would give a customer’s address book.
Do not put secrets in flags or traits
Client-side keys are public. Anyone who finds the key in your app can request flags and see the answers. So never place passwords, tokens, private URLs or confidential pricing rules inside flag values or traits that a client-side SDK can read.
Flags are not permissions
A flag that hides a button is a convenience, not a lock. A determined person can call your server directly even if the button is hidden. The server must still check whether the person is allowed to perform the action, using its own authentication and authorisation.
If a feature must be restricted, enforce the restriction on the server. Use the flag only to decide whether to show the interface. Otherwise the flag becomes a false sense of safety.
Minimise personal data
| Data | Should it be an identifier or trait? | Safer alternative |
|---|---|---|
| Email address | No | Internal user ID, plus a trait like email_domain if truly needed |
| Full name | No | Not needed for flags |
| Exact date of birth | No | A trait like age_band |
| Home address | No | A trait like region |
| Health or financial details | Never | Do not send at all |
| Plan name | Yes | Fine, it is business data |
A cloakroom needs a ticket number, not your home address. If the cloakroom collected addresses it would be holding data it does not need, and a thief who stole the ticket book would learn far too much. Give Flagsmith only what the flags need.
Protect the keys
- Keep server-side and Organisation keys in a secrets manager, never in source code or chat messages.
- Rotate keys if they may have leaked, and after staff with access leave.
- Use separate keys per Environment so a leak in Development cannot touch Production.
Control who edits what
Use groups and permissions so that only trusted members can add overrides or change traits in Production. Review the audit log regularly. Chapter 23 explains how it helps.
Privacy regulations
Where identifiers can be linked to a person, rules such as GDPR in Europe and similar laws elsewhere can apply. Work with your privacy team to document what data you send, why, where it is stored and how it can be deleted. Self-hosting Flagsmith can help companies that need data to stay within their own infrastructure, though it also brings the responsibility to secure and operate it.
Thinking like an attacker
Security teams often ask, “What could a curious stranger do with what is visible?” Applying this to identities gives a short list. A stranger who finds the client-side key could request flags for any identifier they invent, which shows them the names of your flags and the values they take. They could also try to send traits that claim to be premium. If a flag then unlocks a paid feature that your server never double-checks, the stranger gets it free. None of this is a defect in Flagsmith; it follows from sending decisions to places you do not control. The defence is to enforce rules on your own server.
Flag names are visible
Flag names travel to the client. A name like “launch_secret_partner_deal_2027” reveals plans to anyone who reads the response. Choose names that describe behaviour without disclosing business secrets, such as “checkout_new_payment_sheet”.
Separation of duties
The person who creates an override in Production should ideally differ from the person who approves risky changes, at least for sensitive flags. Some organisations use change approval features for this. Check the current documentation for what your plan offers.
| Risk | Example | Control |
|---|---|---|
| Public key misuse | A stranger reads flag names and values | No secrets in flags, neutral flag names |
| Trait spoofing | A browser claims plan equals premium | Server-side checks for anything of value |
| Leaked server key | Key posted in a public repository | Secrets manager, rotation, scanning tools |
| Over-broad access | Everyone can edit Production identities | Groups, least privilege, audit log reviews |
| Stale personal data | Old identities kept for years | Retention rule and cleanup job |
23Monitoring, Audit and Debugging Identities
When a customer says “I cannot see the new feature”, good tools turn a mystery into a short checklist.
The audit log
Flagsmith records changes made in the dashboard and through the API: who changed what, and when. When a person’s experience changes unexpectedly, the audit log often reveals that an override was added, a segment edited or a trait updated. Reviewing it is the equivalent of reading a diary of the system.
The debugging checklist
Is it the right Environment?
Production, Staging and Development have separate identities and defaults.
Is it the right identifier?
Compare the exact text the application sent with what you searched for. Watch for capitals and spaces.
Does the identity have the expected traits?
A missing or misspelled trait is the number one cause of “not in segment” problems.
Which layer decided?
Read the reason next to the effective flag: override, segment or default.
Is the application reading a stale cache?
The dashboard may show the correct answer while the app still holds an old one.
Did something change recently?
Check the audit log for edits near the time the problem began.
A detective asks the same questions at every case: right place, right person, right facts, who made the decision, and has anything changed lately. The checklist above is the same routine applied to flags.
Things worth measuring
| Signal | What it tells you | Action if unusual |
|---|---|---|
| Flag request latency | Whether Flagsmith calls are slow | Check network, caching, timeouts |
| Error rate on flag requests | Reachability or key problems | Verify keys, status page, defaults |
| Count of identities growing rapidly | Possibly random or session based identifiers | Fix identifier choice |
| Number of identity overrides | How many one-off exceptions exist | Review and clean up |
| Percentage of requests using defaults | How often fallback is used | Investigate outages or misconfiguration |
Logging with care
When logging which flag value a person received, log the identifier and the result, but avoid logging full trait sets that contain personal data. Logs are often kept for a long time and viewed by many people, so apply the same minimisation rules you use for the identities themselves.
A debugging story
A customer named Ravi writes to support: “The new reports page works for my colleague but not for me.” A support engineer opens the Production Environment, searches for Ravi’s identifier and reads the effective flags. The reports flag is off, and the reason says “Environment default”. That means no segment matched. The engineer opens Ravi’s traits and sees “plan = Premium” with a capital P, while the segment looks for “premium”. The cause is a spelling difference in one application. The fix is to send lowercase values consistently, and the support engineer adds a short temporary override so that Ravi can use the page today. The whole investigation takes minutes because the dashboard shows both the answer and the reason.
Testing with a test identity
A very handy habit is to keep a handful of named test identities in Staging, for example one per important segment. Engineers can sign in as these identities, or call the API with their identifiers, and see exactly what each kind of customer would see. When a new segment rule is written, testing against these identities catches mistakes before any real customer sees them.
Alerting
Do not rely on people noticing problems. Add alerts for a rising error rate on flag requests, for an unexpected jump in the count of identities, and for a high share of requests falling back to defaults. Alerts turn a slow, quiet problem into a prompt, visible one.
24Advantages, Disadvantages and Trade-offs
Identity-based targeting is powerful, but it is not free. An honest look at both sides helps teams use it wisely.
Precision
Release to exactly the people you intend, from one person to millions.
Safety
Test with staff first, then expand. A problem touches few people, and a flag change reverses it in seconds.
Consistency
A person sees the same behaviour every time, which builds trust and enables fair experiments.
Support speed
Fix or unlock one customer without code changes or releases.
Complexity
More rules mean more combinations to understand. Testing every combination is hard.
Data responsibility
Storing identities and traits brings privacy duties and cleanup work.
Drift and debt
Stale traits and forgotten overrides lead to behaviour no one can explain.
Dependence
The product leans on another service. Defaults and caching must cover its absence.
| Trade-off | One side | Other side | Balanced approach |
|---|---|---|---|
| Precision versus simplicity | Many segments and overrides | One flag for everyone | Few, well named segments |
| Freshness versus speed | Ask Flagsmith every time | Cache aggressively | Short cache with background refresh |
| Privacy versus power | Many traits give richer targeting | Few traits protect people | Only traits a segment truly uses |
| Remote versus local evaluation | Rules stay private | Faster, no per-call network | Remote by default, local for hot paths |
A tailor who measures every customer produces a perfect fit but needs more time and more records than a shop selling one size. Identity-based flags are the tailor: better results, extra care.
25Design Patterns That Work
A pattern is a solution that many teams have found useful again and again. These are the ones that matter most for identities.
Pattern 1: The staff-first ring
Release every new feature in rings. The innermost ring is a segment of staff accounts, marked with a trait such as is_staff. The next ring is a pilot segment of friendly customers. The outer ring is a percentage rollout across everyone. Each ring adds people and confidence. If a problem shows up, only the inner rings are affected.
flowchart LR
A["Ring 1: Staff, is_staff = true"] --> B["Ring 2: Pilot customers, pilot = true"]
B --> C["Ring 3: 10 percent of all identities"]
C --> D["Ring 4: 50 percent"]
D --> E["Ring 5: Everyone"]
A restaurant tests a new dish on the kitchen crew, then regular guests, then the whole dining room. Each group tastes it before the next, and the chef adjusts the recipe along the way.
Pattern 2: Traits as the single vocabulary
Agree on a small, documented list of traits, and build all segments from that list. Everyone then speaks the same language: product managers, engineers and support staff all know what “plan equals premium” means.
Pattern 3: Kill switch with exceptions
Every risky feature gets a flag that can switch it off for everyone in seconds. Identity overrides then handle exceptions in either direction: keep the feature on for a trusted tester during an incident, or switch it off for one troubled account without touching the others.
Pattern 4: Sticky experiment assignment
For experiments, use a stable identifier and a percentage split. Record which variant each person saw in your analytics, along with the identifier. Later analysis can then join results with assignments.
Pattern 5: Entitlement by segment
Use a plan or entitlement trait, set from billing events, so that “which features does this customer have?” lives in one place. Segments read the trait. Changing a plan changes the trait, and the flags follow.
| Pattern | Problem it solves | Identity feature used |
|---|---|---|
| Staff-first ring | Safe, gradual release | Traits, segments, percentage split |
| Traits as vocabulary | Confusion across teams | Traits |
| Kill switch with exceptions | Incidents | Environment default, identity overrides |
| Sticky experiment assignment | Fair comparisons | Stable identifier, percentage split |
| Entitlement by segment | Paid features | Plan trait, segments |
Pattern 6: Dedicated test identities
Keep a small, named set of identities in Staging, and in Production if your policy allows, that represent each major kind of customer: a free user, a paying user, an administrator, a staff member and a user from each important country. Every release, run through a checklist as each of these identities. This turns the abstract question “does our targeting work?” into a concrete, repeatable test that any engineer can perform.
Pattern 7: Expiry by design
For temporary overrides, add a reason and an end date in the ticket system the moment you create them. A weekly reminder lists overrides older than their end date. This tiny routine keeps one-off exceptions from becoming permanent mysteries.
26Anti-Patterns to Avoid
An anti-pattern looks like a good idea at first and causes pain later. Recognising these early saves a lot of cleanup.
Email as the identifier
Looks natural, but emails change and are personal data. Identity history breaks the day someone updates it.
Session ID as the identifier
Every visit becomes a new identity. Rollouts shuffle and the identity list explodes.
Override everything
Hundreds of one-off overrides replace real segments, and nobody can explain the product logic.
Secrets in traits
Client-readable data should never include tokens or confidential rules.
Flags as permissions
Hiding a button is not security. The server must still check permissions.
Trait sprawl
Fifty inconsistent traits, with duplicate names and no owner, make segments unreliable.
| Anti-pattern | Symptom | Remedy |
|---|---|---|
| Changing identifier format | Everyone looks new, overrides vanish | Plan a migration, copy overrides and traits first |
| Test identities in Production | Odd records mixed with real customers | Use a dedicated test Environment |
| Forgotten overrides | One customer behaves differently for no known reason | Expiry reminders, periodic review |
| Different trait spellings across apps | Segments match only some apps | One shared trait dictionary |
| No defaults in code | Features misbehave during an outage | Define safe defaults for every flag |
| Flag evaluated inside loops | Slow pages, extra load | Read once, reuse |
Writing important phone numbers on loose paper scraps feels quick. Months later the scraps are lost, duplicated and out of date. A tidy address book, like a tidy trait dictionary, feels slower at the start and saves enormous effort later.
27Best Practices and Common Mistakes
Habits that keep identity design healthy, and the mistakes teams most often make without them.
Best practices
Pick the identifier first
Choose a stable, private, unique one and document it before writing the first flag.
Keep a trait dictionary
One page lists every trait, its type, allowed values, owner and update source.
Prefer segments to overrides
Use overrides only for true one-offs and put a reason and end date in the ticket.
Set safe defaults in code
Decide on or off for each flag when Flagsmith cannot be reached.
Separate Environments properly
Test with Staging identities, change Production identities deliberately and with permission.
Minimise personal data
Send only what segments need and prefer bands and regions to exact details.
Review regularly
Each release, scan overrides, stale identities and unused segments.
Rehearse failure
Switch off Flagsmith access in Staging and watch how the product behaves.
Common mistakes
| Mistake | Why it happens | Prevention |
|---|---|---|
| Editing the wrong Environment | Top bar not checked | Confirm the Environment name before every change |
| Expecting traits to update instantly everywhere | Caches hold old answers | Know your cache time, refresh when testing |
| Assuming a missing trait means false | Missing traits mean the rule does not match | Send explicit values |
| Using identity for everything | It feels precise | Use plain Environment flags for global switches |
| Forgetting segment priority | Order is invisible in daily use | Review the order when adding segment overrides |
| Treating the dashboard as the source of truth for plans | Convenient to type there | Keep billing data in your database, push traits from it |
If a new teammate cannot explain in one minute why a given customer sees a given feature, your identity design has become too complicated. Simplify before adding anything new.
28Real-World Scenarios
Imaginary but realistic stories show how the pieces fit together. The companies below are invented for illustration only.
Scenario 1: The online bookstore
PageTurn, a fictional bookstore, wants a faster checkout. The team builds a flag called “checkout_new_payment_sheet”. The default is off. They create a segment “Staff” from the trait is_staff and switch the feature on there. After a week they add a segment “Frequent readers” from a trait orders_last_year greater than five, then a ten percent rollout across everyone else. One customer, Meera, reports that the new sheet hides her saved card. Support adds an identity override that turns the feature off for Meera only, and engineers fix the problem in the next release. Then support deletes the override.
Scenario 2: The business software vendor
LedgerLeaf, a fictional accounting product, sells to companies. Every user identity carries account_id and account_plan traits. The advanced reporting module is switched on by a segment “Plan is enterprise”. A sales engineer needs to demonstrate the module to a prospect with a standard plan, so an identity override is added for the prospect’s admin only, with a note that it expires after fourteen days. The override is removed on schedule and the audit log records both steps.
Scenario 3: The mobile game
QuestBlock, a fictional mobile game, experiments with a new tutorial. Before sign-in, players have a random device identifier, saved on the phone. Half of the identifiers see the new tutorial, and the assignment is recorded in analytics. After sign-in the game keeps using the device identifier for this experiment so no player sees the tutorial change mid-session, while using the user ID for features tied to the player’s account.
Scenario 4: The bank-style app that must be careful
A fictional regional bank app shows an investment dashboard to eligible customers. Eligibility is decided on the bank’s servers. The flag only controls whether the screen appears. The identity holds an opaque customer reference and a coarse trait, “region”, never account balances or personal details. If the flag service is unreachable, the safe default hides the new dashboard, and the older screen continues to work.
| Scenario | Identifier | Key traits | Main tools used |
|---|---|---|---|
| Online bookstore | Internal user ID | is_staff, orders_last_year | Segments, percentage rollout, one temporary override |
| Business software | Internal user ID | account_id, account_plan | Segments by plan, timed demo override |
| Mobile game | Device ID for experiments, user ID for account features | platform, level_band | Percentage split, stable assignment |
| Bank-style app | Opaque customer reference | region | Server-side permission checks, safe default, minimal data |
These stories are like different kinds of shops using the same cash register. The machine is identical, but a bookstore, a software seller, a game maker and a bank each configure it to match their own customers and their own care level.
Lessons across all four
- A stable, private identifier was chosen first.
- Segments handled groups, and overrides handled genuine exceptions.
- Sensitive decisions stayed on the server.
- Safe defaults covered the case when the flag service was unavailable.
- Temporary overrides were removed after use.
Scenario 5: The streaming service
StreamNest, a fictional video service, wants to try a new home screen layout. The team creates a flag with two variants and a percentage split of fifty-fifty across signed-in identities, using the internal user ID. Both variants are logged in analytics along with the identifier. After two weeks, the analysts compare watch time between the groups. Because assignment was sticky, no viewer switched layouts during the test, so the comparison is fair. The winning layout is released to everyone by changing the Environment default, and the old segment rules are deleted.
Scenario 6: The travel booking site
RoamEasy, a fictional travel site, must hide a currency converter in countries where it is not licensed. A segment based on the trait country removes the feature in those places. The team also adds a rule on the server that refuses to process conversions for those countries, because a flag alone does not enforce the law. The identity page lets support confirm quickly why a traveller in one country sees the converter while another does not.
What to notice
In every story the flags decide what is shown, while the business-critical checks live elsewhere. Identities supply the knowledge of who is asking, and segments and overrides turn that knowledge into decisions. The pieces are simple, and the skill lies in combining them carefully.
29Planning a Migration of Identity Design
Sometimes a team realises its early identity choice was wrong. Fixing it is possible, but it deserves a plan.
Typical triggers
A product launched with email addresses as identifiers, or with session IDs, and now wants a stable user ID. Or a product that used one identity per account now needs per-user experiments. The new design means new identifiers, which means Flagsmith will see everyone as new.
A safe migration path
Inventory what exists
List identity overrides, important traits and which segments rely on identifiers rather than traits.
Decide the new identifier format
Document it and confirm every application can produce it.
Rehearse in Staging
Create the new identities with their traits and overrides using a script, then compare results with the old ones.
Copy overrides and traits
Script the transfer for Production, with logging and a way to repeat it.
Switch the applications
Release the new identifier in a controlled way, ideally behind its own flag.
Watch and tidy
Monitor errors and complaints, then delete the old identities after a safe period.
Because the number used for bucketing comes from the identifier, changing identifiers changes buckets. People who were inside a ten percent rollout may fall outside it, and vice versa. Schedule the change when no sensitive rollouts or experiments are running.
Changing all membership card numbers in a club is like moving house: possible with planning, painful without. You label boxes, move in stages, forward the post and keep the old address active for a while.
30Frequently Asked Questions
Short answers to the questions people most often ask about identities.
Do I have to use identities at all?
No. If every user should see the same thing, plain Environment-level flags are simpler. Use identities when you need to treat people differently.
Is an identity the same as a user of the Flagsmith dashboard?
No. Dashboard users are members of an Organisation. Identities are the end users of your product, stored per Environment.
Can the same person be in two Environments?
Yes, as two separate identities with the same identifier. They do not share traits or overrides.
What happens if I send a new identifier I have never used?
Flagsmith creates the identity automatically and returns flags using segments and defaults. There is no error.
How many traits should an identity have?
As few as your segments need. Every trait must be kept correct and may be personal data.
Should I use the email address as the identifier?
It is better not to. Emails change and are personal data. Use an internal, stable user ID.
Why does a person not see a feature even though they are in the right segment?
Common reasons are a higher priority segment or identity override with a different value, a cache in the application holding an older answer, or a missing or misspelled trait. Use the effective flags view to see which layer decided.
Is it safe to put an Environment key in a mobile app?
Yes, if it is the client-side key, which is designed to be public. Never put a server-side key or Organisation key in a client application.
Can I give a feature to one person only?
Yes, with an identity override. Use it for genuine one-offs and remove it when finished.
Does a percentage rollout keep the same people when I increase it?
Generally yes, because the bucket number is derived from a stable identifier. People already included stay included while more are added. Check the current documentation for details.
What happens to flags if Flagsmith is unreachable?
The SDK uses cached values if it has them, and otherwise the default values you wrote into your code. Choose those defaults carefully.
Should I delete old identities?
A cleanup routine is wise, especially to honour privacy requests and to keep the list manageable. Decide a retention rule with your privacy team.
Are feature flags a replacement for permissions?
No. Flags decide what to show or enable. Permissions protecting data must be enforced on the server.
Can I use identities for A/B testing?
Yes. Use a stable identifier and a percentage split, record the variant each person saw in your analytics and compare results. Flagsmith provides the assignment, and your analytics tools provide the measurement.
Do traits sent from the browser need to be trusted?
No. Treat them as claims. Use them for convenience, and verify anything important on the server.
Where should I read more?
The official Flagsmith documentation is the best source for exact, current details about SDK methods, permission names and limits, because those details change between releases.
A short glossary to keep nearby
| Word | Plain meaning |
|---|---|
| Identity | One end user, account or device known to Flagsmith inside an Environment |
| Identifier | The text label that names an identity |
| Trait | A key and value fact stored on an identity |
| Segment | A saved group defined by rules over traits |
| Override | A special answer for a person or a group that beats the default |
| Environment default | The general answer for everyone not matched by anything more specific |
| Effective flag | The final answer a person receives after all rules are applied |
| SDK | A small library that lets your application talk to Flagsmith |
| Drift | A stored trait that no longer matches reality |
| Bucket | A stable number derived from an identifier, used for percentage rollouts |
Keep this glossary beside your trait dictionary. When a new teammate joins, ten minutes with these definitions and the identity page for a test customer is often enough to make the whole system click. Revisit the words whenever a conversation becomes confusing, because most disagreements about flags turn out to be disagreements about which of these words someone meant.
31Summary and Key Takeaways
A final walk through the essentials, in plain words.
An identity in Flagsmith is a named end user, account or device that lives inside one Environment. It is named by a single identifier, described by traits and, when needed, given special answers by overrides. When the application asks for flags, Flagsmith finds or creates the identity, collects the rules that apply and returns a personalised list, deciding in a clear order: identity override first, segment override second, Environment default last.
The most important choices come early. Pick a stable, unique and private identifier. Keep a small, shared trait dictionary. Prefer segments to overrides, and use overrides only for real exceptions that you remove afterwards. Treat traits as claims rather than proofs, keep secrets out of client-visible data and enforce real permissions on the server. Cache results, set safe defaults, and plan for the day the flag service cannot be reached.
- An identity is an end user, account or device inside one Environment, named by a stable identifier and described by traits.
- Flagsmith decides per feature in a fixed order: identity override, then segment override, then Environment default.
- Choose an internal, stable, private identifier such as a user ID, never an email address or a session ID.
- Use segments for groups and percentage rollouts, and keep identity overrides for short-lived, genuine exceptions.
- Traits are claims from the app: keep them few, fresh and free of secrets, and enforce real permissions on your own server.
- Plan for failure and cleanup with caching, safe defaults, regular override reviews and a way to delete identities.