Feature State in Flagsmith
The small record that decides what every user sees: what a feature state is, where it lives, how it is layered, how it changes, how it is read, and how to keep thousands of them tidy and safe, explained from the very first idea to production-grade practice.
Picture a large railway station with one giant departure board. Every train has a fixed name on the board, such as “Evening Express to Mumbai.” The name never changes. But beside it, a small panel shows the current status: on time, delayed by ten minutes, platform changed, or cancelled. Passengers do not argue about the name of the train. They look at the status panel, because the status is what tells them what to do right now.
In Flagsmith, the name of a thing you can control is called a feature, and the status panel beside it is called the feature state. The feature is the label. The feature state is the answer. It tells your application, for one feature, in one place, for one person, whether the thing is switched on and what its value is. Everything else in Flagsmith, the environments, the segments, the rollouts, the approvals, exists to decide, protect, and deliver that small answer.
This guide teaches the feature state from the ground up. We will learn what a state is, what it contains, where it lives, how states are layered so that special groups and single users can get special answers, how states change, how they are versioned and recorded, how they travel to your application, and how to avoid the mistakes that trip up many teams. We assume you know nothing yet. Every new word is explained the first time it appears, and every big idea comes with an everyday comparison.
Flagsmith is a living product. Screen names, plan limits, and some options change between versions. This guide teaches the lasting ideas. When you need an exact button name, field name, price, or limit, check the official Flagsmith documentation for the version you use.
1Why “State” Is the Heart of Feature Flags
A feature flag platform can seem to be about many things: dashboards, keys, rollouts, experiments. Underneath all of them is one simple idea, the state.
What does “state” mean?
In everyday language, the state of something is its condition at a given moment. A door is in the state “open” or “closed.” A traffic light is in the state “red,” “amber,” or “green.” A bank account is in the state “balance of five thousand rupees.” The state is not the thing itself. It is the current answer to the question, “What is it like right now?”
Programmers use the word the same way. A program has state when it remembers something that can change. Changing state is how programs react to the world. And one of the great ideas of modern software delivery is to take a particular kind of state, the on and off position of a capability, out of the program’s code and keep it in a place where people can change it safely, without releasing new code.
The problem with state buried in code
Suppose a developer wants a new checkout page to be hidden until the business is ready. The simplest approach is to write a line in the code that says “show new checkout: false.” To change it, someone must edit the code, test it, and release a whole new version. If the page misbehaves in production, undoing it needs another release. The state of the capability is hidden inside the program, and changing it means changing the program.
The idea behind a feature state
A feature flag platform moves that decision out of the code. The code asks a question, “Is new checkout on for this user?” and a separate system supplies the answer. That answer, stored and managed outside the program, is the feature state. Because it lives outside the code, a person can change it in seconds, with a click, with proper permissions and a written record.
Change without releasing
A state can be changed while the program keeps running, with no build, no test run, and no deployment.
Different answers for different places
Development, Staging, and Production can each hold a different state for the same feature.
Different answers for different people
Employees, beta customers, and one named user can each receive a special state.
Instant reversal
Returning to the previous state is as quick as making the change, which makes experiments safe.
A written history
Every change is recorded, so people can see what the state was, who changed it, and when.
Business control
Product and support staff can manage states with the right permissions, without waiting for engineers.
Think of a theatre with a lighting board. The lights in the hall are fixed in place and never move. But the board in the control room decides which ones are on, how bright they are, and in which part of the hall. The wiring is the code, and the position of each slider is the state. A lighting operator can change the mood of the whole theatre without touching a single wire.
A short story of a state gone wrong
Rohan works at a food delivery company. His team has a feature for “free delivery above five hundred rupees.” One evening, a colleague edits the state to lower the threshold to fifty rupees, meaning to do it in the test environment. But the screen showed Production. Within ten minutes thousands of tiny orders arrive with free delivery. The team notices the spike in a dashboard, restores the previous state in one click, and the damage is limited to a few thousand rupees. If the threshold had been hidden in code, the same mistake would have needed a release to fix. The lesson is not only that states are powerful, but also that they must be handled with the same care as code: right place, right permissions, and a written history.
2What Is a Feature State in Flagsmith?
A feature state is the stored answer for one feature in one context, made up of an enabled position and, optionally, a value.
A quick map of Flagsmith
Flagsmith is an open-source platform for feature flags and remote configuration. A feature flag is a switch that turns behaviour on or off without a new release. Remote configuration means storing values, such as numbers or text, that an application reads while it runs. Flagsmith arranges everything in a tree.
Organisation
The top level, usually a whole company. It holds the people, teams, billing, and projects.
Project
A group that usually represents one product or application. The list of features, the segments, and the tags live here.
Environment
A separate place inside a project, such as Development, Staging, or Production, with its own keys.
Feature
A named control that belongs to the project. Its definition, such as name, description, and tags, is shared by all environments.
Feature state
The actual answer for that feature in one environment, or for one segment or identity inside that environment. This is the part that changes.
flowchart TB
ORG["Organisation"] --> PRJ["Project: Food Delivery App"]
PRJ --> FEAT["Feature: free_delivery_threshold"]
PRJ --> ENV1["Environment: Development"]
PRJ --> ENV2["Environment: Production"]
FEAT --> FS1["Feature state in Development: enabled, value 50"]
FEAT --> FS2["Feature state in Production: enabled, value 500"]
ENV1 --- FS1
ENV2 --- FS2
The simplest definition
If a feature is a labelled hook on a hotel key board, the feature state is whether a key is hanging there and which key it is. The label is the same for everybody. The state is a decision about this hook, in this hotel branch, at this moment.
The two halves of every state
A feature state always has two parts that work together.
- The enabled position. A simple yes or no. Is the feature switched on in this context? This is the classic feature flag.
- The value. Optional information attached to the feature, such as a number, a piece of text, or a small block of structured data. This is remote configuration. Even if the feature is switched off, a value may still be stored.
State versus feature: keep them apart in your mind
| Question | Feature | Feature state |
|---|---|---|
| What is it? | The named thing you want to control | The current answer for that thing |
| How many are there? | One per project | Many: at least one per environment, plus overrides |
| How often does it change? | Rarely, such as renaming a description | Often, such as every rollout step |
| Who cares most? | Developers choosing names and types | Everyone: product, operations, support, testers |
| What does code ask for? | The feature’s name | The state that belongs to the asking user |
When someone says “enable the feature in staging,” what they truly mean is “set the feature state of this feature in the staging environment to enabled.” The words feature and feature state are often used loosely, but knowing the difference makes every other idea in Flagsmith easier.
3The Anatomy of a Feature State
Let us open a feature state and look at every part inside it. Each part answers one small question.
flowchart LR
STATE["One feature state"]
STATE --> WHICH["Which feature: the name it belongs to"]
STATE --> WHERE["Where: environment"]
STATE --> FOR["For whom: everyone, a segment, or one identity"]
STATE --> EN["Enabled position: yes or no"]
STATE --> VAL["Value: number, text, or structured data"]
STATE --> MV["Variation shares if multivariate"]
STATE --> META["Version, who changed it, and when"]
Which feature
Every state belongs to exactly one feature. The link to the feature gives the state its meaning, and its name is what your code asks for.
Where: the environment
Every state lives inside one environment. A state in Development has no effect on Production, because the two are stored separately.
For whom
The default state of a feature in an environment applies to everybody. A segment state applies to a group. An identity state applies to one person.
Enabled position
Whether the feature is switched on for this context. The simplest and most used part.
Value
The stored text, number, or data. It may be empty if the feature is only a plain flag.
Variation shares
For multivariate features, the percentage of users that receive each variation in this context.
Version and history
When versioning is available, each saved state carries a version, so that older ones can be seen and restored.
Change details
Who changed it and when. These details are kept in the audit log and are priceless during investigations.
Value types
The value held inside a state can carry different kinds of information. Typically you can store text, whole numbers, true or false values, and, in many versions, structured data written in a common text format used to describe objects. Choose the simplest kind that fits. A single number is easier to read, check, and test than a large block of structured data. If you do store structured data, keep it small and describe its shape in the feature’s description, because mistakes inside a free-form value are not caught until your application tries to use it.
An example state, in words
Take the feature “search_suggestions_limit.” Its state in the Production environment, for everyone, might read: enabled is yes, value is five. Its state for the segment “Mobile users” in the same environment might read: enabled is yes, value is three. Its state for one identity, a tester called “user 4821,” might read: enabled is yes, value is twelve. Three states, all belonging to one feature, all in one environment, each applying to a different audience.
Think of a restaurant menu. A dish has a fixed name, such as “Chef’s Special.” The state of that dish today might be “available, with fish.” For lunch guests it may be “available, smaller portion.” For one regular customer, it may be “available, without salt.” The dish name stays the same. The states are the particular answers for particular audiences.
A feature that is “disabled” may still hold a value. Many applications ignore the value when the feature is off, but some read the value anyway. Decide as a team what your code does when the state is disabled, and write the rule down, so that nobody is surprised.
4The Layers: Default, Segment, and Identity States
A single feature in a single environment can hold several states at once, stacked in layers. Understanding the order of the layers explains almost every surprise in Flagsmith.
Layer one: the environment default state
Every feature has a default state in every environment. It applies to every user who does not match anything more specific. If you change only this layer, everyone in that environment gets the same new answer. It is the bottom layer, and the one that is always there.
Layer two: segment override states
A segment is a saved group of users, defined by rules about their traits. A trait is a fact stored about a user, such as country, plan, or app version. A segment override is a special state for one feature, in one environment, that applies only to users in the segment. For example, in Production, the “Employees” segment might have the new checkout enabled while the default state is still disabled. Segment definitions are shared across the project, but segment override states are stored separately in each environment.
Layer three: identity override states
An identity is a user, device, or account that your application tells Flagsmith about, normally by sending a unique identifier. An identity override is a special state for one feature, in one environment, that applies to exactly one identity. This is the most specific layer. It is perfect for letting a single customer try a beta, or for letting a support engineer reproduce a bug as a particular user.
flowchart TB
subgraph LAYERS["Layers of state for one feature in one environment"]
L3["Layer 3: Identity override state, most specific"]
L2["Layer 2: Segment override states, in priority order"]
L1["Layer 1: Environment default state, always present"]
end
REQ["Request for identity 4821"] --> L3
L3 -->|"No override for this identity"| L2
L2 -->|"No matching segment"| L1
L3 -->|"Override found"| ANS["Answer"]
L2 -->|"Segment match found"| ANS
L1 --> ANS
The order of decision
Flagsmith always looks from the most specific layer to the most general. It first checks for an identity override. If none exists, it looks at the segment overrides for segments that the identity belongs to. If several segments match, a priority order that you control decides which wins. If nothing more specific applies, the environment default state is used. The first layer that has an answer provides the answer, and the layers beneath it are ignored for that user.
| Layer | Applies to | Stored in | Typical use |
|---|---|---|---|
| Identity override | One user | One environment | Beta access for one customer, debugging as a user |
| Segment override | A group matching trait rules | One environment | Employees first, beta group, region, plan |
| Environment default | Everyone in the environment | One environment | The general rollout state |
Think of rules at a cinema. A general rule says tickets cost two hundred rupees. A special rule says students pay one hundred and fifty. A personal note on file says one particular reviewer enters free. The ticket agent checks from the most personal rule to the most general, and the first rule that fits decides the price.
When a feature is enabled in an environment’s default state but a user still sees it off, the cause is almost always a layer above the default: a segment override or an identity override saying “off.” When debugging, always inspect every layer, starting from the top.
Use case: three layers working together
A ride-hailing company has a feature “surge_notice.” In Production, the default state is disabled. A segment override enables it for the “Drivers in Delhi” segment, where the team is testing a new notice. A single identity override disables it again for one driver who asked not to see it. Everyone else sees nothing. Delhi drivers see the notice, except that one driver. Three states, three layers, one clear rule order.
5Enabled and Value: How the Two Halves Combine
A state has an enabled position and a value. How your code treats these two together is a choice. Making that choice clearly prevents a whole family of bugs.
Four possible combinations
| Enabled | Value | Meaning in a typical design | Example |
|---|---|---|---|
| Yes | Empty | A plain flag that is on | New checkout is shown |
| No | Empty | A plain flag that is off | Old checkout is shown |
| Yes | Has a value | The capability is on, and use this setting | Recommendations on, show ten items |
| No | Has a value | Capability is off, setting is stored for later | Recommendations off, but ten is remembered |
The common design rule
A very common and sensible rule is: when the state is disabled, use the safe built-in default and ignore the stored value; when it is enabled, use the stored value. This rule makes the off position a reliable emergency exit. Flipping the switch off always returns the application to the behaviour that was there before, whatever number or text happens to be stored.
When the value is the whole point
Sometimes a feature is purely a configuration value and the enabled position is not used at all, such as a setting called “request_timeout_seconds” with the value thirty. In that case, make the team rule explicit: either the value is always read regardless of the switch, or the switch is always kept enabled. Mixed habits cause confusion, because one developer treats “disabled” as “use default” and another treats it as “feature does not exist.”
Decide the rule once
Write a short team rule that says how enabled and value combine, and implement it in one helper in your code.
Validate values
Check that numbers fall in a sensible range, and that text is not empty, before using them. A bad value should fall back to the default, not break the page.
Keep value shapes stable
If the value is structured data, do not change its shape casually. Old versions of apps may still read the old shape.
Document it
Put the meaning of the value in the feature’s description, such as “number of items, between one and twenty.”
Use case: a value gone wrong
A team stores the number of items in a carousel as the value of a feature. Someone, in a hurry, types the word “ten” instead of the number 10. The application expects a number, fails to read it, and the carousel disappears for thousands of users. A short validation step in the team’s wrapper would have noticed the problem and used the default of eight. The state was changed correctly in the platform, but the habit of validating the value was missing.
Always write the “off behaviour” for every feature in its description. If a stranger can read the description and know exactly what users see when the state is disabled, you have designed the state well.
6One Feature, Many Environments, Many States
The same feature holds a separate default state in every environment. This separation is the main safety feature of Flagsmith.
A reminder about environments
An environment is a separate place where your product runs, such as Development, Staging, or Production. In Flagsmith, each environment stores its own states for every feature, and has its own access keys. An application chooses its environment simply by being given that environment’s key.
A picture of the state matrix
If you imagine a table with features down the side and environments across the top, each cell of the table holds a feature state. The table below shows part of such a matrix for a small project.
| Feature | Development | Staging | Production |
|---|---|---|---|
| new_checkout | On | On for testers segment | Off, on for employees segment |
| search_suggestions_limit | On, value 3 | On, value 8 | On, value 5 |
| recommendations | On | On | On for a 25 percent split segment, then growing |
| kill_switch_payments_v2 | On | On | On |
| old_banner | Off | Off | Off, ready to delete |
The size of this matrix grows quickly. Fifty features across four environments means two hundred default states, before counting any segment or identity overrides. This is why tidy habits, such as deleting finished features, matter so much.
The ladder of states
Because states are separate, a feature can climb a ladder, one rung at a time, collecting evidence on each rung. Development changes freely, many times a day. Staging changes when a release candidate is ready. Production changes only when the business is satisfied and the checks are green.
flowchart LR
D["Development state: on for all, change freely"] -->|"Works as intended"| S["Staging state: set like next Production state"]
S -->|"Tests pass and owners agree"| P["Production state: employees, then percentage, then all"]
P -->|"Problem found"| R["Return Production state to previous version"]
R --> D
No automatic copying, by design
When you change a state in Development, nothing happens in Staging or Production. That separation is deliberate, because automatic copying would defeat the protection that environments create. The consequence is that someone must apply the change in the next environment at the right moment. Teams make this step careful with reviewed requests, scheduled changes, and sometimes scripts that apply the same state to the next environment after tests pass.
Healthy differences and drift
Differences between environments are healthy when they are deliberate. A small number in Development makes screens easy to inspect, and a realistic number in Staging tests layout and load. Problems begin when differences are accidental and unexplained, a situation called configuration drift. A state quietly changed in Staging for a demo and never changed back makes the next rehearsal misleading. Compare environments before each release and explain every difference.
Reading the matrix with three questions
When you look at any cell of the state matrix, three simple questions make it easy to understand. First, which environment is this? The same feature may be on in one and off in another, so never read a state without noticing its column. Second, for whom? The cell may hold a default state and also several segment overrides and identity overrides, so the visible switch is only part of the story. Third, since when? A state changed five minutes ago is a very different fact from a state unchanged for two years. The first points to a possible accident, and the second points to a feature that may be ready for cleanup.
Teams that build the habit of asking these three questions find that most confusing reports can be solved in a few minutes. A tester says, “The feature does not work for me.” The engineer asks which environment the tester is using, which segments the tester belongs to, and what changed recently. The answer is usually found within the layers of state, long before anybody opens the code.
Before every release, set Staging’s states to match what Production will hold after the release, then run the final checks there. If Staging holds different states from what Production will hold, the rehearsal proves nothing.
7Segment Override States in Depth
Segment overrides are where most of the daily work of controlling who sees what takes place. Let us look closely at how their states behave.
Defined once, decided separately
A segment is described by rules over traits, for example “plan equals premium and country equals India.” These rules are part of the project, so a segment means the same thing in every environment. But the state a segment receives for a given feature is stored per environment. This allows the “Employees” segment to receive the new checkout in Production and also in Staging, while the “Beta” segment receives it only in Staging. The groups are shared, and the decisions are local.
Priority among segments
A user can belong to several segments at once. A premium user in India who is also an employee might match three segments. Flagsmith resolves the conflict with an ordered list: the segment override with the highest priority wins. You can reorder the list in the dashboard. Put the most specific and most important overrides at the top, and the broad ones lower down.
| Priority | Segment | State given | Reasoning |
|---|---|---|---|
| 1 | Blocked accounts | Disabled | A safety rule must always win |
| 2 | Employees | Enabled | Staff test everything first |
| 3 | Beta customers | Enabled | Volunteers who want new things |
| 4 | Premium India | Enabled with larger value | A regional launch |
| Default | Everyone else | Disabled | Not released yet |
Segment states can carry values and variations
A segment override is not limited to on and off. It can carry its own value, and for multivariate features it can carry its own variation shares. For example, the segment “Premium users” may receive a search limit of twenty, while the default is five. This turns segments into a powerful way to express business rules without changing code.
Common recipes
Employees first
A segment built on a staff trait gets the state first. Employees forgive mistakes and report problems quickly.
Beta group
Customers who agreed to try new things get the state after employees.
Plan-based access
Premium customers get paid capabilities. These states tend to live for a long time.
Region or language
Release a capability country by country, or only where a law or partner allows it.
App version gate
A rule such as “app version at least 5.2” prevents old apps from waiting for code that was never built into them.
Safety block
A top-priority segment that forces a state off for chosen accounts, such as those under investigation.
A segment silently matching nobody is the most common targeting surprise. The usual cause is a misspelled trait, or an application in that environment that never sends the trait at all. Because identities and traits are stored per environment, a rule that works in Production can fail in Staging. Test every new segment with a known identity before trusting it.
Use case: a staged rollout through segment states
A fintech team releases “instant_transfer.” On Monday the Production state for the Employees segment is enabled. On Wednesday the Beta segment is added. On Friday a segment that uses a percentage split rule, covering ten percent of all users, is given the enabled state. At each step they watch error rates and transfer success. Because each step is a small edit to a state, any step can be undone in one click.
8Identity Override States and Traits
The most specific layer of state belongs to a single person. Used well, it solves difficult problems. Used carelessly, it creates a mess.
Identities live inside an environment
When your application tells Flagsmith about a user, sending an identifier and perhaps some traits, that identity is recorded in the environment whose key was used. A person who exists in Production does not automatically exist in Staging, unless your Staging application also reported them. This separation is healthy, because test users and real users never get mixed. It also means that traits used by segments must be sent by every environment’s application, or the segments will not match there.
What an identity override does
An identity override is a feature state attached to exactly one identity in exactly one environment. It beats every segment override and the environment default. That is its strength. If a customer’s chief technology officer asks to try a beta capability next week, a single identity override is the cleanest way to grant it. If a support engineer must reproduce a strange bug a customer reports, an identity override on a test account lets her see the system exactly as that customer would.
Traits: facts that drive the layers
Traits are the facts stored about identities, and segments are rules over traits. Because the quality of your segment states depends on the quality of your traits, it pays to design them with care.
- Use stable names. A trait called “plan” should always be called “plan,” in every application and every environment.
- Use consistent values. “premium” and “Premium” are different to a computer. Agree on the exact spellings.
- Keep them small and useful. Send the few facts your rules really need, such as country, plan, and app version.
- Avoid sensitive data. Do not send names, email addresses, or health details as traits unless you truly must, and have a legal reason.
- Send traits from every environment. Otherwise, rehearsals in Staging will not predict Production.
| Need | Better tool | Why |
|---|---|---|
| Give a whole group early access | Segment override state | One rule covers everyone, now and in the future |
| Let one customer try a beta | Identity override state | Exactly one person, no new rule needed |
| Reproduce one user’s bug | Identity override state | See the system as that user does |
| Release to hundreds of chosen users | Segment based on a trait or list | Hundreds of personal overrides are slow to manage and hard to audit |
| Block one account from a capability | Identity override or top-priority segment | Safety rules should be explicit and visible |
Think of a school. A general rule applies to all students. Another rule applies to the football team, and a note in one student’s file allows her to use the library after hours. If you find yourself writing personal notes for two hundred students, you have probably needed a new group rule all along. Identity overrides are personal notes, to be kept few and meaningful.
Identity overrides are easy to forget. A personal override created for a short test may stay forever and quietly give one user a different experience from everyone else, long after the rest of the system has moved on. Review identity overrides on a schedule, and remove the ones no longer needed.
Anonymous users
A visitor who has not logged in has no stable identifier. Applications often create a random identifier, store it in the browser or on the device, and use it as the identity. If the visitor later logs in, their identity may change, and with it their state. Plan for this by deciding whether to use the user, the account, the organisation, or the device as the identity. A business product often uses the company as the identity, so that every employee of one customer sees the same state and support is never confused.
9Multivariate States: Many Versions, Shared Out
When one yes or no is not enough, a state can hold several variations, each with a share of the users.
What a multivariate state holds
A multivariate feature has a control value, which is the normal behaviour, plus two or more variations, each with its own value. In each environment, the state records a percentage for every variation. The control takes whatever percentage remains. For example, variation B may have ten percent, variation C ten percent, and the control the remaining eighty.
| Variation | Value | Development state share | Production state share |
|---|---|---|---|
| Control | Blue button | 25 percent | 80 percent |
| Variation B | Green button | 25 percent | 10 percent |
| Variation C | Orange button | 25 percent | 10 percent |
| Variation D | Red button | 25 percent | 0 percent |
The variations themselves, their names and values, belong to the feature. But the percentages are part of each environment’s state. This lets Development spread users evenly, so developers see every version, while Production exposes only a careful slice to the new ones.
How a person is placed into a variation
Flagsmith must give each person the same variation each time, otherwise a user might see a blue button on one page and a green one on the next. It uses a technique called consistent hashing. The identity’s identifier is combined with the feature’s own identifier and put through a hash function, a mathematical scrambler that always gives the same output for the same input, but whose outputs look random and spread evenly. The output is turned into a number from zero to one hundred, and the variations occupy slices of that range according to their percentages. Because the same inputs give the same number, a user’s experience is stable. And because the feature’s identifier is mixed in, the same unlucky users are not always in the first slice of every feature.
Imagine giving every person in a stadium a permanent seat number from one to one hundred, decided by a fixed formula using their name and the name of the game. For a test, you ask people in seats one to ten to wear green, and seats eleven to twenty to wear orange. If you widen the green group, you add more seats, and nobody who was already green has to change colour.
Changing shares mid-experiment
Because the placement is determined by number ranges, changing a percentage shifts the boundaries between slices. Users near a boundary may move from one variation to another. For a gradual rollout, that is acceptable, since you only grow the new variation. For a scientific experiment, it can spoil the results, because a user who saw version B yesterday might see version A today. Treat a change of shares during an experiment as the start of a new experiment.
Plan variation shares before the experiment starts. Write down the start date, the shares, the number you will measure, and the earliest date you will look at the results. This simple note prevents most arguments and mistakes.
Feeding experiments with state
A state only decides who sees what. Judging the result is another job. Flagsmith can pass information about the variation a user received to analytics tools through integrations, so that the analysis is done where your business numbers already live. Decide the measurement first, run for whole weekly cycles, and do not stop the moment one side looks better, because chance can easily fool you.
10From Stored States to the Answer Your Code Gets
When your application asks about a feature, Flagsmith must pick one answer out of all the stored states. Let us follow that choice step by step.
The question from the application
An application normally asks Flagsmith for flags using an SDK, a small library for its programming language. It supplies the environment key, and, for personalised answers, the identity’s identifier and traits. The SDK then returns, for each feature, the enabled position and the value, which your code uses to choose a behaviour. You also give a default in code, used if no answer can be obtained.
flowchart TB
START["Request: identity, traits, environment key"] --> FIND["Find the environment from the key"]
FIND --> LOAD["Load all states for each feature in that environment"]
LOAD --> ID{"Identity override state exists?"}
ID -->|"Yes"| PICK1["Use identity state"]
ID -->|"No"| SEG{"Identity matches a segment with an override?"}
SEG -->|"Yes"| PICK2["Use highest priority matching segment state"]
SEG -->|"No"| DEF["Use environment default state"]
PICK1 --> MULTI{"Is the chosen state multivariate?"}
PICK2 --> MULTI
DEF --> MULTI
MULTI -->|"Yes"| HASH["Place identity in a variation using stable hashing"]
MULTI -->|"No"| OUT["Return enabled and value"]
HASH --> OUT
Remote evaluation
In remote evaluation, the SDK sends a request over the network, and Flagsmith’s servers run the steps above and reply. This works with the public client-side key and is the normal way for web pages and mobile apps. The cost is a network trip for each fetch, so applications fetch once at the start of a session and keep the answers in memory.
Local evaluation
In local evaluation, a back-end server uses its secret server-side key to download all the states and rules of an environment, called the environment document, and runs the steps itself, from memory. It refreshes the document in the background. Checks become extremely fast, and the server keeps working through a short outage using the last known states. The trade-off is that changes arrive at the next refresh instead of instantly.
| Aspect | Remote evaluation | Local evaluation |
|---|---|---|
| Key | Client-side or server-side | Server-side, secret |
| Where states are resolved | On Flagsmith’s servers | Inside your own server |
| Speed of a check | A network request per fetch | Almost instant, from memory |
| Freshness of a changed state | On the next request | After the next background refresh |
| During an outage | Needs cached answers or defaults | Keeps last known states |
| Best for | Browsers and mobile apps | Busy back-end services |
The default: your safety net
A default is the behaviour your code uses when it cannot get an answer, for example during a network problem, or if a feature has been deleted by mistake. The best default is almost always the old, proven behaviour. Defaults are written in your code next to the check, not stored in Flagsmith. For a new release feature, the default should be off. A default that turns a brand new capability on when the service is unreachable means a routine network glitch could expose every user to unfinished work.
Two different people can see two different answers for the same feature at the same moment, and both can be correct. The layers, the segments, and the variation shares exist precisely to make answers depend on who is asking. Always ask “for whom?” before saying what a state “is.”
11How a State Is Changed
A state can be changed in several ways. Each way has its own strengths, and teams usually mix more than one.
Directly in the dashboard
A person with permission opens the feature, edits the state in one environment, and saves. Quick and visible, and ideal for Development and low-risk changes.
Through a change request
A person proposes a change, someone else reviews and approves it, and only then does it take effect. Best for critical states in Production. Availability depends on your plan.
As a scheduled change
The change is set to take effect at a chosen future time, which suits coordinated launches that must start at a precise moment.
By the Admin API
A script or pipeline changes states through a programming interface, for example enabling a feature in Staging after tests pass. Needs a carefully guarded administrative token.
By infrastructure as code
States are described in reviewed files and applied by a tool, such as a Terraform provider, so that the desired state is written down and repeatable.
By automation after an alarm
A script sets a state back automatically when a monitoring alarm fires during a rollout, shrinking the time to recover.
Choosing a way for each environment
| Environment | Usual way to change states | Reason |
|---|---|---|
| Development | Direct, by anyone on the team | Speed matters, risk is low |
| Test | By automation, with fixed values | Repeatable tests |
| Staging | By testers or pipeline, mirroring the next release | A trustworthy rehearsal |
| Production | By reviewed change requests or scheduled changes for critical features | Second pair of eyes and a record |
flowchart LR
A["Person proposes state change in Production"] --> B["Change request created"]
B --> C{"Reviewer approves?"}
C -->|"No"| D["Comments and revision"]
D --> B
C -->|"Yes"| E{"Apply now or schedule?"}
E -->|"Now"| F["State changes immediately"]
E -->|"Later"| G["State changes at chosen time"]
F --> H["Audit log and webhook"]
G --> H
H --> I["Applications receive new state"]
What happens at the moment of change
When a state is saved, Flagsmith writes the new state to its store and records the change in the audit log. It may also fire a webhook, a message sent to another system, such as a post in a team chat channel. The delivery layer then makes the new state available to applications. Applications using remote evaluation see it on their next request, and applications using local evaluation see it after their next refresh. The whole journey from click to effect often takes only seconds.
Change only one thing at a time in Production. If you change a state and also deploy new code in the same hour, and something breaks, nobody can tell which change caused it.
12Versions, History, and Going Back
Because a state can be changed in a second, it must also be possible to see what it used to be and to return to it. History is the safety net under every change.
The audit log
The audit log is a diary of everything that changes in Flagsmith: who made the change, which feature and environment it touched, what the old and new states were, and when. When something odd happens in production, the first question is always “what changed?” and the audit log answers in seconds. For compliance, it also proves that changes followed approved procedures.
Feature versioning
In versions of Flagsmith that support feature versioning, the states of a feature in an environment are saved as numbered versions. A new version is created each time changes are published, and earlier versions can be inspected, and in many cases restored. This turns recovery from “try to remember the old value” into “go back to version twelve.” It also allows a new version to be prepared and published together at a chosen time, along with its overrides.
Version one: created
The feature is created, switched off. This is the starting state in the environment.
Version two: employees
The Employees segment is given an enabled state. Everyone else is still off.
Version three: a small percentage
A ten percent split segment is added. Guardrail numbers are watched.
Version four: problem found
A bug appears at fifty percent. The team goes back to version three while the bug is fixed.
Version five: fully on
After the fix, the state is enabled for everyone, and the history shows the whole story.
Comments and reasons
A short note explaining why a change was made, such as “raising to twenty-five percent after clean results from ten,” makes the history readable by people who were not there. Make writing such notes a team habit, particularly for Production.
Snapshots and exports
Teams also keep their own record of important states. Some export the environment’s configuration regularly through the Admin API and store it in version control. Others describe states as code with an infrastructure tool, so that the written plan is always the record. Both approaches protect against rare disasters, such as a mistaken bulk deletion, and make drift easy to detect, since the real states can be compared with the saved ones.
Think of a document with tracked changes. You can always see who edited which sentence and when, and you can go back to an earlier version if the latest edit was a mistake. Feature state versions and the audit log give a flag platform the same confidence to make quick changes, because the old state is never really lost.
Going back to an old state is only safe if the code still understands that state. If the application changed in between, restoring an old value, such as an old data shape, may break things. Always check that code and state are compatible before restoring.
13State and the Continuous Delivery Pipeline
Feature states are what make continuous delivery calm. They separate the moment code arrives from the moment users see it.
A quick reminder about the pipeline
Continuous Delivery means every code change travels through an automatic assembly line, called a pipeline, that builds, tests, and prepares it so that it could be released at any moment. The same package moves from stage to stage. Only the settings change, and feature states are among those settings.
Deploy is not release
Technical event
Code reaches the servers. Handled by the pipeline. Can happen many times a day, since new code is hidden behind a disabled state.
Business event
Users start to see a capability because a state changed. Handled by people, in careful steps, and reversible in seconds.
flowchart LR
C["Commit"] --> B["Build and tests"]
B --> DEV["Deploy to Development"]
DEV --> STG["Deploy to Staging"]
STG --> PRD["Deploy to Production with state disabled"]
DEV -.->|"uses Development key"| SD["Development states"]
STG -.->|"uses Staging key"| SS["Staging states"]
PRD -.->|"uses Production key"| SP["Production states"]
SP --> REL["Release: change Production state in steps"]
Mirror staging to production
As a release approaches, set the Staging states to match what Production will hold after release, then run the final checks. If Staging holds different states from what Production will hold, the rehearsal answers the wrong question. Add a step before each release that compares the two environments and explains every difference.
Trunk-based development and hidden work
In trunk-based development, everyone merges small changes into one shared main line every day. Half-finished work will land there. A disabled feature state keeps it invisible while it travels to production in the normal pipeline. The state turns the main line into a safe place for unfinished ideas.
Use case: the weekly release train
A retail company releases to Production every week. On Monday the pipeline deploys the candidate to Staging, and the Staging states are set to mirror the plan: three new features on, one held back. Testers check on Tuesday and Wednesday. On Thursday the release manager creates change requests for the Production states. After two approvals, the changes are applied in steps through the afternoon while the team watches dashboards. The code had been in Production for days. Only the states changed on release day.
A theatre can build a new set behind a closed curtain while the current play continues in front. Building the set is the deploy. The state of the curtain, open or closed, is the feature state. Each environment is a separate theatre with its own curtain, so the crew can open the curtain in the practice theatre a hundred times, and the real audience never sees it.
14The State Journey of a Rollout
A rollout is nothing more than a planned series of state changes. Seeing it as a journey from one state to the next makes it easy to plan, measure, and reverse.
flowchart LR
S0["State 0: off everywhere, code deployed"] --> S1["State 1: on in Development"]
S1 --> S2["State 2: on in Staging for testers"]
S2 --> S3["State 3: Production on for employees"]
S3 --> S4["State 4: Production on for beta customers"]
S4 --> S5["State 5: Production on for ten percent"]
S5 --> S6["State 6: Production on for fifty percent"]
S6 --> S7["State 7: Production on for everyone"]
S7 --> S8["State 8: stable, old path kept as exit"]
S8 --> S9["State 9: code removed, feature deleted"]
S4 -.->|"Problem"| S3
S5 -.->|"Problem"| S3
S6 -.->|"Problem"| S0
Each step has an entry rule and an exit rule
| State | What is true | Enter when | Move on when |
|---|---|---|---|
| 0: off, deployed | Code is in Production, hidden | Pipeline succeeded | Development tests pass |
| 3: employees | Staff use the real feature | Staging rehearsal passed | No new errors for a day |
| 5: ten percent | A small slice of customers | Beta feedback is positive | Guardrails healthy for two days |
| 6: fifty percent | Half of customers | Ten percent was clean | No load problems, support calm |
| 7: everyone | Fully released | Fifty percent was clean | Stable for a few weeks |
| 9: removed | Old path and feature are gone | Stable period ended | Finished |
Reversal is also a state change
The most valuable property of this design is that reversal is the same kind of action as progress. Moving from state six back to state three is simply another edit of the state, and it takes the same few seconds. No deployment is needed, because the code never left. This is what makes a bold launch calm: the exit is always one click away.
Writing the plan down
Before the first step, write the plan: the states in order, the audience of each, the guardrail numbers to watch, the time to wait at each step, and the person who may press the reverse button. A written plan transforms a nervous rollout into a routine. A good plan also says what the safe state is, so that anyone on call can move there without asking permission.
Rehearse the reverse path before you need it. In Staging, practise moving from a later step back to an earlier one, and confirm that the application behaves well at each step, including the off state.
15Propagation, Caching, and Consistency of States
A state changed in a dashboard does not reach every server at the same instant. Understanding the delay keeps surprises small.
The journey of a changed state
Saved
The new state is written into Flagsmith’s store, and the audit log records who made the change.
Made available
The delivery layer makes the new state available to requests. In the hosted service, this layer is spread across the world so that answers come from nearby.
Fetched by applications
Applications using remote evaluation see it on their next request. Servers using local evaluation see it at their next background refresh. Mobile apps and browsers see it when they next refresh their stored answers.
Acted upon
The application’s code reads the new state and chooses a different behaviour for the next request.
Eventual consistency
For a short while after a change, some servers hold the old state and others hold the new. This is called eventual consistency: all servers will agree in the end, but not at the very same instant. For most capabilities, a few seconds of disagreement is harmless. A user might see a new button on one page load and not on the next. For some journeys it matters more.
Making a decision sticky
For multi-step journeys, such as a checkout of several screens, a change in the middle would be confusing. The common remedy is to read the state once at the start of the journey, store the answer with the user’s session, and reuse that stored answer for the rest of the journey. The next journey reads the state again, and receives the new answer. This is called a sticky decision.
Polling interval
Servers using local evaluation refresh every so often. A longer interval means a longer delay before a change is seen.
Cached answers in apps
Mobile apps and browsers keep answers for a while to save data and battery. A kill switch needs a short refresh, or pushed updates.
Saved copies
A server that restarted during an outage may start from a saved copy that is slightly old until it reaches the service.
Many servers
A fleet of servers refreshes at slightly different times, so for a moment answers differ across servers.
Choosing freshness by importance
| Kind of state | How fresh it must be | Suggested approach |
|---|---|---|
| Emergency kill switch | Seconds | Short refresh or pushed updates, and a tested off state |
| Rollout percentage | A minute or two is fine | Normal refresh interval |
| Tuning value | Minutes | Normal refresh interval |
| Long-lived permission state | Not urgent | Longer cache to save traffic |
When you announce a flip such as turning off a feature during an incident, remember that mobile apps may take longer than servers to notice. Count the delay when you decide how long to wait before declaring the problem fixed.
16Testing With States
When behaviour depends on states that can change at any moment, testing needs a few extra habits.
The explosion of state combinations
If a program has one feature, there are two possible behaviours. With two features there are four, and with ten features there are one thousand and twenty-four. With thirty there are over a billion. Each layer of override adds more possibilities for each user. Nobody can test every combination, and fortunately nobody needs to, since most features do not touch each other. The skill lies in testing the combinations that matter.
A practical approach
Test both positions of every state
Automatic tests should cover the disabled path, which is the current behaviour, and the enabled path, which is the new behaviour.
Test the planned Production states
Run a main suite with states set exactly as Production will hold them, since that is what real users will meet.
Test the next set of states
Also run the suite with the states planned after the next change, so switching them on holds no surprises.
Test interacting features together
When two features touch the same screen or data, test all four combinations, or better, avoid making features depend on each other.
Test the layers
For important features, check that the identity override beats the segment override, and that the segment override beats the default. Use known test identities.
Try it in Production, carefully
A segment state for employees lets real people use the real feature on real systems, which reveals what Staging cannot.
Repeatable tests need fixed states
An automatic test must give the same result every time. A test that depends on a state that people change during the day would be unpredictable. The cure is a dedicated test environment in which states are fixed and changed only by the test team, or a wrapper in your code that lets the test supply the answer directly: “for this check, pretend the feature is enabled with value five.” Everything else then behaves normally.
Temporary environments
Larger teams sometimes create a temporary environment for each pull request. The pipeline creates the environment through the Admin API, sets the states the new feature needs, runs the tests, and deletes the environment afterwards. Two developers can then test conflicting states at the same moment. The price is the effort of automation and the need to clean up reliably, since forgotten temporary environments pile up.
Never point automatic tests at the Production environment and let them change states. A faulty test could switch a live capability on or off for real customers. Tests belong in a test environment or in temporary ones.
Practising the safe state
A kill switch that has never been tested is a hope, not a safety device. Practise setting important states to their safe position in Staging, and occasionally in Production during quiet hours, to confirm that the product degrades gracefully. A page that crashes when recommendations vanish is a problem best found during practice.
17Advantages, Disadvantages, and Trade-offs
Managing behaviour through states gives great power and also real costs. An honest engineer knows both sides.
Advantages
- Behaviour changes in seconds without releasing new code.
- Each environment, segment, and person can have its own answer.
- Reversal is the same quick action as progress.
- Every change is recorded, so investigations are fast.
- Product and support teams can act within clear permissions.
- Releases become small and reversible steps.
- Values can be tuned live to respond to load or business needs.
- Experiments are possible through multivariate shares.
Disadvantages
- A wrong change of state can cause an outage as easily as bad code.
- Layers make it harder to say what a given user sees.
- States multiply with features, environments, and overrides.
- Forgotten overrides and old states turn into technical debt.
- Environments can drift apart unnoticed.
- Changed states take a short time to reach every server and device.
- Values are free-form and a typo is not caught by a compiler.
- Personal data in traits needs care.
Key trade-offs to decide on purpose
| Decision | Option A | Option B | Guidance |
|---|---|---|---|
| Many segment states or few | Fine-grained control | Simple, readable rules | Keep rules few and well named, so anyone can explain them |
| Segment or identity override | Rule for a group | Personal exception | Prefer segments, and keep personal overrides rare and reviewed |
| Direct or reviewed change | Fast | Safer | Review critical Production states, allow direct change elsewhere |
| Remote or local evaluation | Fresh, simple | Fast, resilient | Local for busy servers, remote for browsers and apps |
| Store a value or hard-code | Flexible, changeable | Simple, checked by compiler | Use a state only for things that must change without release |
| Created by hand or as code | Easy to start | Repeatable, reviewable | Move to code when the number of states and teams grows |
When not to use a state
Not every setting deserves to be a changeable state. A rarely changed setting that is safe in code, a constant that must be checked at build time, or a secret that should never travel through a flag platform, are all better handled elsewhere. The more things you place behind changeable states, the more places you must watch.
18Security, Permissions, and Privacy of States
Changing a state can change what millions of people see in seconds. That power must be guarded, and the information flowing through states must be handled with respect.
Who may change which states
Least privilege means each person gets only the permissions needed for their job. Flagsmith lets administrators grant permissions at the organisation, project, and environment levels, to individuals or to groups. At environment level, typical permissions include viewing the environment, updating feature states, managing segment overrides and identities, and creating or approving change requests.
| Role idea | Typical state permissions | Why |
|---|---|---|
| Developer | Change Development freely, propose Production changes | Speed where it is safe, review where it is not |
| Tester | Change Staging states | Rehearse realistically |
| Release manager | Approve Production change requests | A second pair of eyes |
| Support | Manage identity overrides in Production | Help one customer without touching global state |
| Product owner | View, schedule through requests | Control timing without risking accidents |
| Platform owner | Administer keys, settings, permissions | Keep the system healthy |
Keys and tokens
Applications read states using environment keys. The client-side key, for web pages and mobile apps, is treated as public, because it can only fetch the states for one user. The server-side key is secret, because it can download the whole environment document, including every segment rule and override. Keep it in a secrets manager. Administrative tokens, used to change states by script, are the most powerful of all and must be guarded like a production database password.
Anything that reaches a browser or a phone can be inspected by a curious person. Never place secrets, unreleased product names, or private pricing in values read by client-side code. And never trust a client-side state to guard something important. Enforce access to paid content or private data on the server.
Do not store secrets in values
A state’s value may travel to many systems, and can appear in logs, caches, and analytics tools. Passwords, tokens, and private addresses belong in a secrets manager. Use values for behaviour and harmless settings.
Privacy of identities and traits
Identities and traits can contain personal information. Send only what your rules truly need, use opaque identifiers instead of names and email addresses, and send traits such as plan or country rather than sensitive facts. Running Flagsmith on your own servers keeps personal data under your control, which can help with laws such as the European GDPR or India’s data protection law. With local evaluation, identity details can stay inside your own servers while only the rules are downloaded.
Governance habits
- Keep the audit log. Many compliance rules require proof of who approved Production changes.
- Review access regularly. Every few months, remove permissions nobody needs.
- Use single sign-on. People should lose access when they leave the company.
- Separate duties. The person who proposes a critical change should not be the only one who approves it.
- Plan break-glass access. Define a documented emergency path for setting a state to its safe position quickly, with review afterwards.
19Monitoring, Logging, and Detecting Drift
If states change what users see, you must watch the effect of every change, and watch the states themselves for things that look wrong.
Tag signals with the state
The most useful habit is to record which state a request ran with. Then any graph can be split into two lines: users with the capability and users without. The question “is the new checkout slower?” becomes a comparison of two lines. Flagsmith can send state information to analytics and monitoring tools through integrations, and many teams also add the state to their own logs.
Metrics
Numbers over time, such as error rate, response time, and orders per minute. Perfect for dashboards and alarms.
Logs
Detailed records of events, including the state each request used. Useful for investigating one user’s report.
Traces
The path of one request through many services, showing where time is spent when a state changes behaviour in one of them.
Change markers
Notes on graphs saying when a state changed, so that a jump in a number can be linked to its cause in a second.
Guardrail metrics
When a rollout starts, a team writes down guardrail metrics, numbers that must not get worse no matter how good the new capability looks: error rate, slowest-request time, payment success, app crashes, and support contacts. If any guardrail crosses its limit, the rollout pauses or reverses.
flowchart TB
A["Change state to next step in Production"] --> B["Webhook posts to team channel"]
A --> C["Audit log records the change"]
A --> D["Applications receive the new state"]
D --> E["Metrics tagged with environment and state"]
E --> F{"Guardrails healthy?"}
F -->|"Yes"| G["Wait, then continue to next step"]
F -->|"No"| H["Alarm fires"]
H --> I["Set state back to previous version"]
I --> J["Investigate with logs and traces"]
Detecting drift
Drift is the slow growth of unexplained differences between environments. To catch it, compare environments before every release, listing features whose states differ and explaining each. Some teams write a short script that fetches the states of two environments through the Admin API and prints the differences. Others keep the intended states in files and compare them with the real ones on a schedule, raising an alarm when they disagree.
Looking for states that no longer matter
- Features unchanged for months. A state that has been fully on or fully off for a long time may no longer provide any safety or choice.
- Orphaned overrides. Identity overrides for users who left, and segment overrides for segments that no longer exist, are noise.
- States with no readers. Evaluation counts, where your plan offers them, show features no one reads any more.
- Staging differing from Production without a reason. This is the most common sign of a misleading rehearsal.
Watch the plumbing too
Monitor how often SDKs fail to reach Flagsmith, how old the states held in each server are, and how often applications fall back to defaults. A rising number of fallbacks is an early warning that something is wrong between your applications and the flag service, long before users complain.
20Performance, Scale, and Reliability
A state is read on almost every request, so at the scale of a large company, even small delays and rare failures matter.
Keep reads cheap
If every read needed a trip across the internet, a page with twenty features would feel slow. The standard approach is to fetch once, keep the answers in memory, and refresh in the background. Back-end servers use local evaluation so that each read takes only a tiny slice of time. Browsers and apps fetch at the start of a session and reuse the answers.
Keep the data lean
The size of an environment’s data grows with the number of features, segments, and overrides. A large environment document means a bigger download and more memory on every server. Tidy habits keep it light: delete finished features, remove unused segments, and avoid thousands of identity overrides when one segment rule would do.
Treat deleting old states as a performance practice as well as a tidiness practice. Every dead feature and every forgotten override adds to what every server must download, store, and evaluate.
Designing for failure
Cached states
Applications keep the last known states in memory, so a short outage of the flag service goes unnoticed.
Safe defaults in code
Every read supplies a default, normally the old and proven behaviour.
Timeouts
Applications should not wait forever for the flag service at start-up. A short limit with a fallback keeps start-up quick.
Saved environment data
Where supported, a server keeps a saved copy of the environment, so a restart during an outage still has real states.
Separate Production from the rest
Heavy testing against Development must never share limits or connections with Production traffic.
Mobile apps and old versions
Once an app version is installed on a phone, its code cannot change until the person updates. A feature state is therefore a remote control for capabilities already inside the installed app. You can set a faulty capability to its safe state on millions of phones without waiting for an app store review. But states for code that does not exist in older versions need care, so segment rules often include a condition on the app version.
Ask one simple question of any design: “If Flagsmith disappeared this minute, what would our users see?” The right answer is “the safe, old behaviour, with no errors.”
21Patterns and Anti-Patterns
A pattern is a proven solution to a repeating problem. An anti-pattern is a tempting solution that causes trouble. Learn both.
Patterns worth adopting
Create everything off
New features begin disabled in every environment, and are enabled deliberately, starting in Development.
Mirror staging to production
Set Staging to the state Production will have after release, so the rehearsal predicts reality.
Release through segments
Employees first, then beta, then a percentage, then everyone, each as a small state change.
State as code
Describe states in reviewed files and apply them with automation, so they are repeatable and drift is easy to detect.
Wrap the SDK
One thin layer of your own handles names, defaults, value checks, and test overrides.
Sticky decisions
For multi-step journeys, read the state once, remember it with the session, and reuse it.
Anti-patterns to avoid
The unexplained override
A segment or identity override created for a short test and never removed. It quietly gives some users a different experience from everyone else, and nobody remembers why.
Better approach
Give every override a reason and an owner, review overrides on a schedule, and remove them when their job is done.
The playground staging
A Staging environment where anyone changes states at any time. It no longer resembles Production, so passing tests there means nothing.
Better approach
Treat Staging as a rehearsal stage. Change its states only to mirror the planned Production state, and keep experiments in Development.
Enabled-by-default creation
Creating a new feature with an enabled state that is copied to every environment. Production may show an unfinished capability the moment the feature exists. A reused name can be even worse, as the 2012 Knight Capital incident showed, where a repurposed flag woke old code on one server and cost roughly four hundred and forty million dollars in under an hour.
Better approach
Create features disabled, never reuse a feature name, and verify that every server runs the same version before changing a state.
The unsafe default
A fallback in code that treats an unreachable flag service as “enabled.” A routine network glitch then silently exposes everyone to unfinished work.
Better approach
For release features, default to the old, proven behaviour. For kill switches, choose the default that protects the system.
Hundreds of personal overrides
Using identity overrides to hand-pick users for a rollout. It is slow to maintain, hard to audit, and makes the environment data heavy.
Better approach
Describe the audience with a segment rule built on traits, and keep identity overrides for rare, individual cases.
Secrets and big blobs in values
Storing passwords, tokens, or large blocks of content in a state’s value because it is convenient. Values travel widely, may be visible to client code, and are not checked by a compiler.
Better approach
Keep secrets in a secrets manager and large content in a content system. Use values for small, validated settings.
22Best Practices and Common Mistakes
These habits come from many teams learning the hard way. Following them saves you from most of the pain.
Best practices
- Create features disabled. Enable their states deliberately, starting in Development.
- Know the layers. Identity overrides beat segment overrides, which beat the environment default. Check all three when debugging.
- Decide how enabled and value combine. Write the rule once, put it in one helper in your code, and validate values before use.
- Write the off behaviour in the description. A stranger should know what users see when the state is disabled.
- Prefer segments over personal overrides. Rules scale and can be explained.
- Always supply safe defaults in code. The default should be the old, proven behaviour.
- Mirror Staging to the next Production state. Make the rehearsal predict the performance.
- Compare environments before each release. Explain every difference or fix it.
- Release in small steps with guardrails. Employees, beta, a percentage, then everyone, watching the numbers at each step.
- Review critical Production changes. A second pair of eyes is cheap protection.
- Add a reason to every Production change. A short note makes history readable.
- Announce Production changes in a shared channel. Visibility makes investigations faster.
- Practise the safe state. Nobody should see the off position for the first time during an emergency.
- Clean up overrides and features. Remove personal overrides, unused segments, and finished features regularly.
- Describe states as code when they grow. Repeatable beats hand-clicked.
Common mistakes
Editing the wrong environment
The classic accident. Check the environment name and colour before every change, and make Production look different.
Forgetting a higher layer
A state enabled by default can still appear off because of a segment or identity override above it.
Wrong type or typo in a value
Typing a word where a number is expected can make a page vanish. Validate values before use.
Traits missing in lower environments
If Staging does not send the traits a segment needs, the rule matches nobody and the rehearsal misleads.
Changing shares mid-experiment
Moving percentage boundaries shifts users between variations and spoils the results.
Rolling out too fast
Going from zero to everyone in one step removes the safety of a staged release.
Restoring an old state blindly
An old value may no longer fit the current code. Check compatibility first.
Server key in a mobile app
Anyone can extract it and read every state in the environment. Use the client-side key on user devices.
A checklist before changing a Production state
Am I in the right environment?
Check the name and colour at the top of the screen.
Which layer am I changing?
Know whether you are editing the default, a segment, or one identity, and who it affects.
Was this rehearsed in Staging?
Confirm that Staging held the same state and that the checks passed.
Do I know the safe state?
Be able to say exactly what happens when the state is disabled, and be sure it has been tested.
Are the dashboards open?
Have the guardrail graphs ready and the alerts working before you click.
Does the team know?
Tell support and on-call staff so they can connect any reports to your change quickly.
It also helps to talk openly about culture. States work best in teams where setting something back to its safe position in Production is treated as a normal, healthy action and not as a failure to be hidden. If people fear blame, they will hesitate to reverse a bad change, and the greatest strength of a state, its speed, is wasted. Teams that celebrate a quick, calm reversal, and then study it without blame, become safer over time.
23Real-World and Industry Examples
The idea of controlling exposure through changeable state, in careful steps, is common to the best-known engineering organisations. Here are public lessons, followed by an illustrative story.
Facebook (Meta): employees first, dark launches
Facebook became famous for showing new capabilities to its own employees before the public, and then to growing slices of users. In 2008 it launched its chat system by running the new back-end code for real users without showing the chat window, so engineers could see how servers coped before anyone could use it. A gating system lets engineers choose audiences and turn capabilities off quickly. For a service with billions of users, controlling who sees what through changeable state is the only sensible way to change anything.
Netflix: judging a release by the numbers
Netflix, together with Google, open-sourced a delivery platform called Spinnaker, which supports strategies such as canary and blue/green releases. They also built an automated canary analysis tool that compares the numbers of a new version against the old before a release continues. Netflix also runs a very large number of experiments, so many viewers see slightly different pages and recommendations at any moment. The lesson for Flagsmith users is to let measurements, not feelings, decide whether to advance a state.
Amazon: small, staged, reversible changes
At a conference in 2011, an Amazon engineer reported that the company deployed to production on average roughly every eleven seconds, thanks to heavy automation and teams that own small services. Amazon has also described rolling changes through stages, from early, low-risk ones to larger ones, with automatic checks between stages, and a culture that prefers changes that can be undone. A feature state in Flagsmith brings the same shape to individual capabilities.
Google: one main line, careful gating
Google engineers largely work from a single shared main line of code, relying on strong automated tests and switches to keep it healthy. New behaviour is often hidden behind a switch and revealed to a small group before wider release. A shared feature list with separate decisions per environment, which Flagsmith expresses through feature and feature state, follows the same idea.
Etsy and Flickr: the early pioneers
Flickr’s 2009 talk about releasing more than ten times a day helped start a movement. Etsy, the marketplace for handmade goods, became another famous example, openly sharing its habit of releasing many times a day with small changes, strong monitoring, and configuration switches that let it turn parts of the site on and off. Their public writing taught a generation of teams that frequent change is safer, not more dangerous.
Knight Capital: the cautionary tale
In 2012 a trading firm deployed new software to only some of its servers, while a repurposed flag woke up old code on a server that had not been updated. The firm lost roughly four hundred and forty million dollars in under an hour. The lesson is not that switches are dangerous, but that names must never be reused, deployments must be verified as complete, and the ability to move a state back to safety quickly must be practised.
An illustrative story: a bank app and a new transfer screen
The following story is invented, shown to tie the ideas together. A bank has a Flagsmith project with Development, Staging, and Production environments. A developer creates a feature called “instant_transfer_v2.” It is created disabled in every environment, with a description that says what the screen does, who owns it, and that the off behaviour is the old transfer screen.
Week one: Development state
The Development state is enabled. Developers merge small pieces daily, hidden behind the disabled states in Staging and Production. Automatic tests cover both positions.
Week two: Staging state
The same build reaches Staging. The QA testers segment receives an enabled state, and performance tests run against realistic data.
Week three: Production, employees
A reviewed change request enables the state for the Employees segment in Production. Staff use the new screen on the real system for two days.
Week three: beta and ten percent
The Beta segment receives the state. Then a segment based on a ten percent split is added. At each step, the team checks transfer success rate, errors, and support calls against the group still on the old screen.
A hiccup and a fast reversal
At twenty-five percent, failures rise for one bank partner. The team returns the Production state to the previous version within a minute, investigates in Staging, fixes the issue, and resumes two days later. No redeployment was needed.
Cleanup
After three stable weeks at full strength, the old screen and the feature check are removed from the code. The feature is archived, then deleted, and its states disappear from every environment. The audit log keeps the whole story.
Think of introducing a new medicine. It is tested in a laboratory, then in a small, closely watched trial, and then offered to more people, with doctors ready to stop immediately if something looks wrong. Each stage has its own rules and records. Feature states give software teams the same careful, staged, reversible path.
Patterns in all these stories
| Source | Main idea | Flagsmith equivalent |
|---|---|---|
| Employees first and dark launch | Segment override states in Production | |
| Netflix | Judge by numbers, run experiments | Multivariate states and guardrail metrics |
| Amazon | Small, staged, reversible steps | A rollout as a path of states with a way back |
| Shared main line with gating | Shared feature, separate states per environment | |
| Etsy and Flickr | A culture of frequent change | Deploy often, release by changing a state |
| Knight Capital | Reused flag and incomplete deployment | Never reuse names, verify deployments, rehearse the safe state |
24Frequently Asked Questions
Short, clear answers to questions that beginners and experienced engineers often ask about feature states in Flagsmith.
25Summary and Key Takeaways
You have travelled from the fear of changing a live product to the calm of small, reversible, recorded changes of state. Here is what to remember.
A feature state in Flagsmith is the small stored answer that tells your application what to do: whether a feature is enabled, what its value is, and which variation a person receives. It lives inside an environment, and it is stacked in layers, so that one feature can give a different answer to a single user, a group, or everyone. Changing a state is quick, recorded, and reversible, which is what turns risky releases into calm experiments. The practical habit to carry away is to always ask three questions before touching any state: in which environment am I, for whom does this change apply, and what is the safe position I can return to?
Key Takeaways
- The label and the answer. A feature is the named control defined once. A feature state is the answer for it, with an enabled position and an optional value, stored separately in every environment.
- Three layers, most specific first. An identity override beats a segment override, which beats the environment default. When a user sees something unexpected, inspect all three layers in that order.
- Decide how enabled and value combine. Write one clear rule, validate values, and describe the off behaviour so that the safe position is always dependable.
- Nothing is copied automatically. Promote states through the environments deliberately, mirror Staging to the next Production state, and compare environments to catch drift.
- A rollout is a path of states. Move from employees to beta to a percentage to everyone, watching guardrail metrics, and remember that reversal is just another state change.
- History makes speed safe. Use the audit log, versions, reasons, and announcements so any change can be understood and undone. Check that code still fits an old state before restoring it.
- Guard and tidy. Apply least privilege, review critical Production changes, keep secrets out of values, supply safe defaults in code, and remove old overrides, segments, and features regularly.