Common Mistakes in Flagsmith
A complete, beginner-friendly guide to the errors that teams make with feature flags and Flagsmith: why they happen, how to recognise them early, what they cost, and the simple habits that prevent almost all of them.
It is a quiet Tuesday afternoon, and an engineer wants to switch off a small experimental button. She opens the flag dashboard, finds the flag, clicks the toggle and goes to make tea. Ten minutes later the support channel lights up. Customers cannot check out. The flag she changed was in the production environment, and it controlled something far more important than a button. She had meant to be in staging. Nothing was wrong with the tool. Nothing was wrong with the engineer. The mistake lived in the gap between a busy person and a screen that looked almost identical in two places.
Feature flags are among the most helpful tools in modern software, and also among the easiest to misuse. They are small, quick and powerful, and those three qualities together make mistakes cheap to commit and sometimes expensive to repair. Almost every team that adopts Flagsmith meets the same handful of problems: flags changed in the wrong place, flags that never get removed, applications that break when the flag service is unavailable, keys that leak and rollouts that go too fast.
This guide collects those mistakes and explains each one from scratch. We assume you know nothing about feature flags or Flagsmith. We explain every new word when it first appears, use everyday comparisons, and for each mistake we describe what it looks like, why it happens, what it costs and how to avoid it. We avoid code listings so that the lessons stay clear and stay correct as screens and libraries change. Where an exact label or default might differ in your version, we say so, and we suggest you confirm it in the current Flagsmith documentation.
1Why Mistakes Happen with Flags
Before listing mistakes, it helps to understand why smart people keep making them. The causes are surprisingly human.
A quick refresher on flags
A feature flag is a named switch that lives outside your program. Your application asks, “is this feature on?”, and a flag service such as Flagsmith answers. Because the answer comes from the service, you can change behaviour in seconds without releasing new code. Flagsmith organises flags in layers: an organisation contains projects, a project contains environments such as development, staging and production, and each environment keeps its own state for every feature. Applications talk to Flagsmith through small code libraries called SDKs, using keys that identify the environment.
Why flags invite mistakes
Changes are instant
A single click can change what thousands of people see. Speed is the benefit, and also the danger.
Environments look identical
Development and production screens are almost the same, so a tired person can act in the wrong one.
Flags cost nothing to create
Because creating a flag is easy, nobody thinks about the cost of keeping it forever.
Effects hide in the code
A flag’s reach is not visible in the dashboard. Only the code knows what it truly controls.
Many hands, little ownership
Several teams touch the same dashboard, and nobody feels responsible for the whole.
Pressure during releases
Flags are used at the busiest moments, when care is hardest to maintain.
A feature flag dashboard is like the control desk in a power station. Every switch is clearly labelled and works perfectly. Yet the biggest accidents in control rooms usually come from a correct action on the wrong switch, a missing label, or a procedure nobody wrote down. The tool is fine. The surroundings and habits are what matter.
The three families of mistakes
Nearly every flag mistake belongs to one of three families. Human mistakes happen at the dashboard: wrong environment, careless changes, unclear names. Design mistakes happen in the code: no defaults, tangled flags, secrets in values. Process mistakes happen in the team: no owners, no cleanup, no review. Knowing the family helps you choose the right remedy, because a human mistake is fixed with guardrails, a design mistake with better code and a process mistake with better habits.
Mistakes are not a sign of carelessness. They are a sign that a system makes the wrong thing too easy. The best prevention is to make the right thing the easy thing.
2A Map of the Mistakes
Before we visit each mistake in detail, here is a map showing where they live and how they connect.
flowchart TB
M["Common Flagsmith Mistakes"] --> H["Human at the dashboard"]
M --> D["Design in the code"]
M --> P["Process in the team"]
M --> O["Operations and hosting"]
H --> H1["Wrong environment"]
H --> H2["Vague names and empty descriptions"]
H --> H3["Changing many things at once"]
D --> D1["No default values"]
D --> D2["Wrong or leaked keys"]
D --> D3["Secrets in flag values"]
D --> D4["Tangled and nested flags"]
D --> D5["Unstable identities"]
P --> P1["Flags never removed"]
P --> P2["No owners or end dates"]
P --> P3["Too-fast rollouts"]
P --> P4["Loose permissions"]
O --> O1["No backups or restore drills"]
O --> O2["Unmonitored task processor"]
O --> O3["Skipped upgrades"]
Reading the map
The map has four branches. The human branch covers what happens at the dashboard: acting in the wrong environment, writing unclear names and changing several things at once. The design branch covers how code uses flags: missing defaults, mishandled keys, secrets stored where they should not be, entangled flags and unstable user identities. The process branch covers how the team behaves around flags: never removing finished flags, leaving them without owners, rolling out too fast and giving too many people too much power. The operations branch applies mainly to self-hosted installations: missing backups, unwatched background workers and delayed upgrades.
The rest of the guide visits each leaf of this tree. For every mistake, we describe how it looks in real life, why it happens, what it costs and how to prevent it. At the end, we bring everything together in a worked example, a diagnostic path and a checklist.
The map is like a road safety leaflet. It groups accidents into types: speeding, ignoring signals, poor vehicle upkeep and fatigue. Each type has its own prevention, and knowing the type helps you recognise your own risky habits before they cause a crash.
| Family | Where it happens | Typical cause | Typical cure |
|---|---|---|---|
| Human | At the dashboard | Haste, similar-looking screens, unclear labels | Guardrails, naming rules, approvals |
| Design | In the application code | Shortcuts, missing fallbacks, unclear ownership of keys | Wrapper, defaults, key discipline, reviews |
| Process | In team habits | No owner, no end date, no review | Lifecycle rules, regular tidy-ups, roles |
| Operations | On servers and databases | Neglected upkeep, no drills | Backups, monitoring, upgrade routine |
3Mistake: Changing the Wrong Environment
This is the most famous flag mistake, and the one with the most dramatic stories. It deserves a careful look.
What it looks like
Someone intends to change a flag in development or staging but is actually looking at production. They toggle the flag, and real customers see an untested change straight away. Sometimes the opposite happens: a person switches a flag off in staging to fix a problem, believes production is fixed too and goes home, while customers continue to suffer.
Why it happens
Environments are deliberately similar: the same flags, the same layout, the same colours. The only difference may be a small name near the top of the page. When people work fast, switch between tabs or follow a link from a chat message, they can easily lose track of where they are. Remember that each environment has its own state for each flag, so the same toggle can be on in one place and off in another, and nothing about the toggle itself says which world it belongs to.
What it costs
The cost ranges from embarrassment to real outages. A wrong click in production can expose unfinished features, break checkout flows or switch off protective kill switches. Even when the mistake is spotted quickly, it takes time to understand what changed, and trust in the flag system takes a hit.
How to prevent it
Say the environment out loud
Before clicking, read the environment name on screen and say it. This tiny habit catches a surprising number of errors.
Limit who can change production
Give most people access to development and staging only. Production changes should belong to a small group.
Use approvals where available
If your edition supports change requests, require a second person to approve production changes.
Announce production changes
Send every production change to a chat channel so mistakes are seen within moments.
Make production look different
Where your tools allow, use distinct environment names or colours, and bookmark each environment separately.
It is like a pharmacist with two identical shelves, one holding practice samples and one holding real medicine. If the boxes look the same, the label on the shelf is the only protection. Careful pharmacies add a second check, a different coloured bin and a rule that two people sign for the real stock.
The mistake is most likely during an incident, when you are in a hurry and following a link. Slow down for exactly two seconds, read the environment name, then click.
4Mistake: Vague Names and Empty Descriptions
A flag with a poor name works perfectly on the day it is created and becomes a puzzle a few months later.
What it looks like
The dashboard contains flags called test, new_feature, temp2 and fix. Their descriptions are empty. Nobody remembers who created them, what they control or whether they are still needed. Even worse, some names mean the opposite of what they appear to say, such as a flag called disable_search_v2 that is on when search version two should be off.
Why it happens
When creating a flag, the focus is on the feature, not on the person who will read the list next year. A quick name feels good enough. The description field is optional, so it is skipped. There is no agreed style, so each person invents their own.
What it costs
Unclear names slow everyone down. People hesitate to touch flags they do not understand, so stale ones stay forever. In emergencies, responders waste precious minutes working out which flag to change. Negative names breed double-negative confusion, such as “turn off the disable flag”, which is exactly the sort of sentence that causes errors under stress.
How to prevent it
Good naming habits
- Describe the behaviour, for example welcome_banner or checkout_new_payment_form.
- Use one consistent style, such as lowercase words with underscores.
- Begin with the product area so related flags sort together.
- Phrase names positively, so that on means the feature is active.
- Write purpose, owner and planned end date in the description.
Naming traps
- Meaningless names such as test1 or new_thing.
- Names with a person’s name, a date or a ticket number as the only clue.
- Negative names such as disable_something.
- Different styles mixed together by different people.
- Leaving the description empty because it is optional.
Naming a flag is like labelling a jar in the kitchen cupboard. A clear label and a date mean anyone can use the jar properly. A blank jar of white powder might be sugar or salt or something worse, and everybody is a little afraid of it.
Agree a one-page naming guide with your team and link it from the place where people create flags. A short, shared rule beats a perfect rule that nobody has read.
5Mistake: No Default Values and No Plan for Failure
The flag service will occasionally be slow or unreachable. What your application does at that moment is decided long before.
What it looks like
An application asks Flagsmith for a flag and assumes an answer will always arrive. When the network hiccups or the service is briefly unavailable, the application shows an error, hangs while waiting or behaves in an unplanned way. Sometimes the unplanned behaviour is that a half-finished feature appears for everyone, because “missing” was treated as “on”.
Why it happens
In development, the flag service is always available, so the failure path is never exercised. The code is written for the happy path and nobody asks what happens when the answer does not come. Defaults feel like extra work.
What it costs
The flag service becomes a hidden single point of failure. A short outage or a network problem in the flag path becomes an outage of the whole product. Worse, an unplanned default can expose features that were never meant to be seen.
How to prevent it
flowchart TD
A["Application needs a flag answer"] --> B{"Fresh cached answer available"}
B -- Yes --> C["Use cached answer"]
B -- No --> D["Ask Flagsmith with a short timeout"]
D --> E{"Answer received in time"}
E -- Yes --> F["Use answer and refresh cache"]
E -- No --> G{"Older cached answer available"}
G -- Yes --> H["Use last known answer"]
G -- No --> I["Use safe default defined in code"]
Reading the fallback chain
The ideal flag read has several layers of protection. First, check for a fresh cached answer, which avoids a network trip entirely. If there is none, ask Flagsmith, but only wait a short time. If an answer arrives, use it and refresh the cache. If it does not, fall back to the last answer that was known, because that is likely to be still correct. If there is no earlier answer at all, use a default defined in the code. Each layer reduces the chance that a flag outage becomes your outage.
- Define a default for every flag, and choose it deliberately. For new, unproven features the safe default is almost always off.
- Set short timeouts so a slow flag service never makes your pages slow.
- Let SDKs keep recent answers in memory or on the device.
- Test the failure path on purpose by blocking access to Flagsmith in a test environment.
A resilient flag read is like a ship’s navigation. The captain checks the satellite position first, then the last known position, then dead reckoning from speed and heading. Losing one source of information does not leave the ship lost.
Choose the default by asking what the safest behaviour is, not the most convenient. For a kill switch that protects a fragile system, the safe default may be to keep the protection on.
6Mistake: Mixing Up Environment Keys
Keys are the quiet connection between your application and the right set of flags. A wrong key produces confusing results that look like bugs.
What it looks like
An application reads flags from the wrong environment because it was given the wrong key. A staging build points to production flags, or a production build points to development flags. A developer sees the feature working on their machine and cannot understand why it is missing after release. Another team sees staging tests pass while production behaves differently, because staging and production were never really separate in the code.
Why it happens
Keys are long, similar-looking strings. They are copied by hand into configuration files and deployment settings, often under time pressure. Different environments need different keys, but configuration files are frequently copied between environments with the key left unchanged. When something works, nobody checks which environment it is actually reading.
What it costs
The cost is wasted debugging time and, in the worst case, test traffic influencing production flags or production flags being changed by test activity. It also destroys the main benefit of environments, which is a safe place to try things.
How to prevent it
- Keep each environment’s key in that environment’s configuration only, never in shared code.
- Name configuration entries clearly, so a key for production cannot be mistaken for one for staging.
- Show the active environment name somewhere in a test or admin screen, so you can see which world the application is reading.
- Add a simple startup check that logs which environment the application connected to, without logging the key itself.
- Review deployment configuration whenever a new environment is created.
Keys are like the keys on a caretaker’s ring. They all look similar, and a labelled tag is the only thing that tells you which door each opens. A caretaker who removes the tags to make the ring tidier will eventually unlock the wrong room, or fail to unlock the right one when it matters.
A tiny diagnostic page that prints the current environment name and the state of a few important flags will solve a large share of “why is it different here?” questions in seconds.
7Mistake: Using the Wrong Kind of Key
Flagsmith provides different kinds of keys for different places. Using them in the wrong place can either expose too much or give you too little.
The two main kinds
A client-side key is designed for applications that run on users’ devices, such as web pages and mobile apps. It can only read flags, so it is safe to include in code that users can inspect. A server-side key is for trusted servers. It can do more, such as enabling local evaluation, where the server downloads the rules and decides flags itself. Because it is more powerful, it must be kept secret. There are also keys for the management interface, which can change configuration and must be guarded even more carefully. The exact names and capabilities can vary by version, so confirm them in the documentation.
What the mistake looks like
Server key in the browser
A secret key is placed in a web page or mobile app, where anyone can extract it and read configuration they should not see.
Management key in a public repository
A key that can change flags is committed to shared code, and anyone who finds it can alter production behaviour.
Client key on a server that needs local evaluation
A server uses the weaker key and misses the faster, more resilient local evaluation mode.
Keys shared across many apps
One key is used by many applications, so nobody can rotate it safely or tell who is using it.
How to prevent it
- Use client-side keys in browsers and apps, and server-side keys only on servers.
- Store secret keys in a secrets manager or protected configuration, never in code repositories, chat messages or documents.
- Rotate any key that may have been exposed, and rotate keys periodically as a habit.
- Use separate keys for separate applications where your setup allows, so you can rotate one without disturbing the others.
- Search your repositories and build logs for accidental key leaks before they are found by someone else.
| Key type | Where it belongs | Secret? | If it leaks |
|---|---|---|---|
| Client-side environment key | Browsers and mobile apps | No, designed to be visible | Low risk, but avoid putting sensitive values in flags |
| Server-side environment key | Trusted servers only | Yes | Rotate immediately, review what it could read |
| Management interface key | Automation and administration | Yes, strictly | Rotate immediately, review the audit log for changes |
The keys are like those in a hotel. The room key opens one door and is handed to the guest. The staff key opens many rooms and stays in the staff area. The master key opens everything and lives in the manager’s safe. Handing the master key to a guest because it is convenient is how a hotel ends up on the evening news.
Once a secret key has been committed to a repository, removing it in a later commit does not erase it from history. Always treat a committed key as leaked, and rotate it.
8Mistake: Putting Secrets or Personal Data in Flag Values
Flag values are convenient places to put configuration, and that convenience tempts people to store things that do not belong there.
What it looks like
Someone stores an access token, a password or a private address in a flag value because it is the easiest way to change it without redeploying. Another person puts a customer’s email address in a trait, or stores internal notes about a user in a value. The flag works perfectly, and the leak is invisible until someone looks at network traffic.
Why it is a problem
Flag values travel. They are sent to applications, and values read by browsers and mobile apps can be seen by anyone who inspects the traffic. They can appear in logs, in cached copies on devices, in audit entries and in webhook messages sent to other systems. A secret stored in a flag is effectively copied to every place the flag travels. Similarly, personal data sent as traits is stored in Flagsmith and may fall under privacy rules and customer promises.
How to prevent it
Safe uses of values
- Display text such as banner messages.
- Limits and thresholds such as page sizes or retry counts.
- Non-sensitive switches that choose between behaviours.
- References to a secret stored elsewhere, not the secret itself.
Never put in values or traits
- Passwords, tokens, private keys and connection strings.
- Names, emails and phone numbers unless truly needed.
- Health, financial or other sensitive personal details.
- Internal notes that you would not want a customer to read.
Use opaque identifiers, such as an internal user number, instead of names and emails. Send only the traits you genuinely need for targeting. Keep secrets in a secrets manager, and let the flag choose which behaviour to use, not carry the credentials.
Putting a secret in a flag value is like writing your safe’s combination on the notice board because it is handy for the staff. It is certainly convenient, and every person who walks past now knows the combination as well.
Add a short review rule: any new flag value that looks like a credential, address or personal detail is rejected. Checking takes seconds and prevents privacy and security headaches.
9Mistake: Never Removing Flags
The quietest mistake is also the most common. Flags are easy to add and surprisingly easy to forget.
What it looks like
A flag was created to roll out a feature. The rollout succeeded months ago. The flag is on for everyone and nothing interesting happens. But the code still contains both the old and the new behaviour, and the dashboard still lists the flag. Multiply this by dozens of releases and the code becomes a thicket of branches that nobody dares to touch.
Why it happens
After a successful release, attention moves to the next project. Cleaning up has no visible reward, and nobody owns it. The flag looks harmless, so it stays. Over time, nobody remembers whether it can be removed, which makes removing it frightening.
What it costs
Each stale flag leaves a dead branch in the code, extra tests, extra reading effort for new engineers and a small chance of an accident. The total, often called flag debt, slows every future change. In rare, dramatic cases an old flag is switched or reused by mistake and old code springs back to life.
flowchart LR
A["Flag created for a release"] --> B["Release succeeds"]
B --> C{"Cleanup scheduled"}
C -- Yes --> D["Remove flag check and old path"]
D --> E["Archive the flag"]
C -- No --> F["Flag stays on for everyone"]
F --> G["Code keeps dead branch"]
G --> H["New engineers cannot tell what is safe"]
H --> I["More flags added on top"]
I --> J["Fear of touching anything"]
Reading the two paths
After a successful release, there is a fork. On one path, cleanup is scheduled, the flag check and the old code are removed and the flag is archived. Nothing is left to confuse anyone. On the other path, the flag stays on for everyone, the dead branch remains and each new engineer has to work out what is safe. As more flags are added on top, the whole system becomes something people are afraid to touch. The difference between the paths is a single decision made at the time of release.
How to prevent it
- Write the owner and the intended removal date in the description of every release flag.
- Include the cleanup task in the original piece of work, so the feature is not finished until the flag is gone.
- Review the flag list monthly, looking for flags that have been fully on or off for a long time.
- Remove the code first, deploy, confirm nothing still asks for the flag, and only then archive it.
Flags are like scaffolding around a building under construction. It is essential during the work and dangerous to leave afterwards. A street lined with scaffolding from finished projects is ugly, obstructs the pavement and is costly to maintain.
Before removing a flag that looks stale, check every application and every active version. Mobile apps in particular can run old versions for months, and those versions may still ask for the flag.
10Mistake: Reusing Old Flag Names
It seems thrifty to reuse a name that already exists. In practice it is one of the most dangerous shortcuts in flag management.
What it looks like
A team needs a new flag and notices an old flag with a suitable name, perhaps one that was used for a previous feature and is now unused. They repurpose it for the new feature, change the description and carry on. Meanwhile, an old copy of the software somewhere still contains code that reacts to that name in the old way.
Why it is dangerous
A flag name is a promise between the dashboard and every piece of code that ever asked for it. Old versions of mobile apps, forgotten services, long-running jobs and archived scripts may still honour that promise in the old sense. When the meaning of a flag changes, those old pieces of code suddenly behave in unexpected ways. The industry has several cautionary stories in which old code, reactivated by a reused flag, caused serious damage within minutes.
How to prevent it
- Treat flag names as permanent and unique. Never reuse a name for a different purpose.
- Create a new flag for a new purpose, even if it feels wasteful.
- Keep a short record of retired names so they are not chosen again by accident.
- Search all repositories and services for the name before creating or retiring a flag.
Reusing a flag name is like giving a new tenant the same phone number as the previous one without telling the old callers. Some of them will keep ringing with expectations that no longer apply, and the new tenant will wonder why strangers are making odd requests.
| Situation | Wrong move | Right move |
|---|---|---|
| Feature finished, name seems handy | Rename the purpose and reuse the flag | Archive the old flag and create a new, uniquely named one |
| Old flag still referenced in an old app | Change its behaviour in the dashboard | Leave it alone until all references are gone |
| New team wants a similar flag | Share the existing one | Create a separate flag per purpose |
| Unsure whether a name was used before | Assume it is free | Search code and the retired names list first |
11Mistake: Tangled and Nested Flags
One flag is easy to reason about. Ten flags that depend on each other are a puzzle with too many pieces.
What it looks like
A feature is protected by one flag, but inside it sits another flag, and inside that a third. A new payment form works only when flag A is on, flag B is on and flag C is off. Nobody can say what the product does when flag A is off and flag B is on. Or a single flag controls several unrelated behaviours, so that turning it off to fix one problem breaks something else.
Why it happens
Flags are cheap, so adding another flag to solve each new problem feels natural. Features grow over time, and each addition gets its own switch. Nobody steps back to ask how the switches relate.
What it costs
With a small number of flags, the number of possible combinations grows very quickly. Three flags make eight combinations. Ten flags make more than a thousand. No team can test them all, so some combinations run in production untested. The product becomes unpredictable, and incident responders cannot tell what turning a flag off will do.
How to prevent it
One flag, one decision
Each flag should answer a single clear question. If you need an “and” in its description, consider splitting it.
Avoid hidden dependencies
If one flag only makes sense when another is on, document it, or combine them into a single flag with more than two outcomes.
Limit nesting
Keep flag checks shallow in the code. Deeply nested flag logic is hard to read and impossible to test fully.
Retire quickly
The fewer flags are alive at once, the fewer combinations exist. Fast cleanup is the best simplifier.
Tangled flags are like a room with a dozen light switches that each control several lamps in different ways. Visitors flip switches at random to find the one that lights the desk, and sometimes plunge the whole room into darkness. A room where each switch controls one lamp is easy to understand even by a stranger.
When a feature needs more than one flag, draw a tiny table of which combinations are allowed. If the table is longer than a few lines, simplify the design before writing the code.
12Mistake: Unstable or Careless Identities
Targeting depends on recognising the same user each time. Careless identities make flags flicker or leak information.
What it looks like
A percentage rollout is set to ten percent, but the application generates a new random identifier on every visit. The same person sees the new feature on one visit and not on the next. Support receives confused reports of “the button keeps appearing and disappearing”. In another case, the application uses an email address as the identity, so personal data is stored in Flagsmith and shown in the dashboard.
Why it happens
Identities are easy to overlook. Developers need to provide something, so they provide whatever is at hand. Anonymous visitors have no user number, so a throwaway value is created each time. The consequences appear only when a rollout or an override depends on the identity staying the same.
How to prevent it
- Use a stable identifier that stays the same across visits, such as an internal user number.
- For anonymous visitors, generate a random identifier once and store it on the device, reusing it each time.
- Prefer opaque identifiers to names and emails, to protect privacy.
- Send only the traits you need, and keep their meaning consistent over time.
- Test a rollout by visiting several times as the same user, and confirm the answer stays the same.
An unstable identity is like a customer who changes name every time they enter a shop. The shopkeeper cannot honour a loyalty discount, cannot remember the customer’s preferences and cannot decide whether this is the fortieth visit or the first. A stable name makes everything else possible.
| Choice | Problem | Better |
|---|---|---|
| New random ID per visit | Rollouts flicker; overrides never apply | Store one random ID on the device and reuse it |
| Email address as identity | Personal data stored and displayed | Use an internal opaque user number |
| Different ID formats across apps | The same person is treated as several users | Agree one identity format across all applications |
| Sending dozens of traits | More data, more risk, more confusion | Send only traits that rules actually use |
If you change how identities are generated, users are treated as new people, and rollouts reshuffle. Plan identity design early, because changing it later affects every percentage rollout in progress.
13Mistake: Confusing Segments and Their Priorities
Segments are powerful groups, and powerful things cause confusing results when their rules overlap.
A short reminder
A segment is a saved group of users defined by rules on their traits, such as users on a premium plan or users in a particular country. In a feature’s settings, a segment override says that users in that segment receive a different state or value from the default. A single user can belong to several segments at once, so more than one override may apply. When that happens, a priority order decides which one wins.
What the mistake looks like
A team creates a beta testers segment that turns a feature on, and a separate europe segment that turns the same feature off for legal reasons. A beta tester in Europe is in both segments. Which result do they get? If nobody thought about priority, the answer depends on an order that nobody chose on purpose. Other typical errors include rules written against a trait name that the application never sends, rules that match nobody because of a typing difference such as capital letters, and rules that match everybody because they are too broad.
How to prevent it
Name segments by meaning
Choose names such as beta testers or premium plan users, so their purpose is obvious in every list.
Check trait names exactly
Confirm the application sends the same trait name and value format that the segment rule expects, including capitalisation.
Think about overlaps
List the segments a user might belong to at the same time, and decide which should win.
Set the priority on purpose
Order overrides so that restrictive or legal rules take priority over convenience rules.
Test with real examples
Look at sample identities in the dashboard and confirm the answer for each combination you care about.
Overlapping segments are like club membership cards. A person may hold a student card and a senior discount card and a loyalty card. Whichever the cashier looks at first decides the price. A sensible shop writes down which card wins, rather than leaving it to whoever happens to be on the till.
Keep the number of segments modest and their purposes distinct. Fifty overlapping segments are almost impossible to reason about, while five clear ones are easy.
14Mistake: Rolling Out Too Fast, or Not Watching
A flag makes it possible to release gently. Many teams throw that gift away by going from nothing to everything in one step.
What it looks like
The code is deployed, the flag is switched on for all users in one click, and the team moves on. Five minutes later the error rate climbs, but nobody is watching. By the time a customer complaint arrives, thousands of people have seen a broken experience. The flag can be turned off in seconds, yet the damage was done during the long minutes of silence.
Why it happens
Speed feels productive. The rollout plan is in someone’s head, not on paper. Monitoring is checked after the fact, not during the change. Teams trust that the feature is fine because tests passed in staging, forgetting that production has different data, scale and surprises.
What it costs
The benefit of a flag is limiting the blast radius of a mistake. A rollout straight to everyone makes the blast radius the whole user base. A slow, watched rollout shrinks it to a few percent, and gives you time to react.
How to prevent it
Internal users first
Enable for staff or a test segment in production, where mistakes are cheap and feedback is fast.
A small percentage
Move to one or a few percent of users, and wait long enough to see real behaviour.
Grow in stages
Increase exposure in steps, pausing at each to compare error rates, speed and business measures.
Keep the exit ready
Know who will turn the flag off, how, and which signals will trigger that decision.
Decide the signals in advance
Before the rollout starts, write down what you will watch and what counts as bad. For example: error rate, response time, completion of the key user task and the number of support contacts. Agree thresholds in advance, so that you do not argue about whether a number is acceptable while it is climbing. Tell the team when the rollout starts and when each step changes.
A fast, unwatched rollout is like opening a new bridge to all traffic at once on its first day without anyone standing nearby. A careful rollout lets a few vehicles cross first while engineers watch the structure, then more, and keeps the barrier ready.
Percentage rollouts and related tools may depend on your edition or plan. Check what is available, and design your rollout plan around what you really have.
15Mistake: Misunderstanding Caching and Delay
A flag change is saved instantly, yet applications may notice it later. Not knowing this causes false alarms and false confidence.
What it looks like
A person switches a flag off during an incident and sees the toggle change in the dashboard. They assume the problem is solved. Minutes later, some servers are still showing the old behaviour, because their SDKs hold cached answers or refresh at intervals. Or the opposite: a person turns a flag on, refreshes their page, sees nothing and decides that the flag is broken, then flips it back and forth in frustration.
Why it happens
Different SDKs and settings behave differently. Some ask the service on every request. Some keep answers in memory for a while. Some servers use local evaluation, downloading rules and refreshing them periodically. Browsers and mobile apps may keep a copy on the device and refresh on a schedule. Most people only learn the behaviour of their own setup after being surprised by it.
How to prevent it
- Learn and write down the refresh behaviour of every application that reads your important flags.
- Choose refresh intervals deliberately, balancing freshness against load.
- For emergency kill switches, make sure the refresh interval is short enough to meet your needs, and test how long a change takes to spread.
- During incidents, verify the effect in the application itself, not just in the dashboard.
- Avoid flipping a flag repeatedly while waiting. Each flip can leave different servers in different states.
| Setup | How quickly a change appears | Watch out for |
|---|---|---|
| Ask on every request | Almost immediately | Heavy load on the flag service |
| Short in-memory cache | Within the cache time | Servers with different cache ages disagree briefly |
| Local evaluation on servers | Within the refresh interval | Intervals set too long for kill switches |
| Stored copy on a device | At the next refresh, possibly on next launch | Offline devices keep old answers |
| Edge proxy or extra cache layer | After the proxy refreshes | Another layer of delay to measure |
It is like changing the opening hours on a shop’s website. The change is saved at once, but a customer who loaded the page ten minutes ago still sees the old hours. Each cache is a customer’s memory, and you cannot instantly wipe every memory.
Time your kill switch. In a test environment, flip it and measure how long it takes for every application to react. Then you will know, not guess, how quickly you can stop a problem.
16Mistake: Asking Too Often
Every flag question has a cost. Applications that ask too often waste time, money and the patience of the flag service.
What it looks like
A server asks Flagsmith for the same flag many times during a single request. A loop checks a flag on every item in a long list. A mobile app contacts the service every time a screen is shown. A browser page asks for the flags again at each step of a flow. The flag service works hard, response times creep up, and costs rise on hosted plans that charge by request volume.
Why it happens
Flag checks look cheap in code: they read like ordinary function calls. When the SDK hides the network trip, developers forget that each call might travel across the internet. The habit of “just ask again when I need it” scales badly as traffic grows.
How to prevent it
Efficient habits
- Read a flag once per request or screen, and reuse the answer.
- Cache answers briefly in memory.
- Use local evaluation on servers so most decisions never touch the network.
- Fetch all flags in one call when a page or screen starts.
- Send identity and traits only when they are needed for targeting.
Wasteful habits
- Calling the service inside tight loops.
- Re-fetching flags on every screen or click.
- Updating traits on every action when they have not changed.
- Polling at very short intervals without need.
- Ignoring request volume until a bill or a slowdown arrives.
Asking too often is like phoning the town hall every few seconds to ask the time. Each call is polite and cheap, yet together they swamp the switchboard. Looking at a clock once and remembering the answer for a moment works better for everyone.
Good client habits often delay or remove the need for a larger flag deployment. Optimise how applications ask before you pay for more capacity.
17Mistake: Loose Permissions and Missing Visibility
A flag dashboard is a lever on your live product. Who may pull it, and who can see it being pulled, are design decisions.
What it looks like
Everyone in the company has administrator rights because it was easier at the start. A single shared login is used by the whole team. Former contractors still have access. Nobody reads the audit log. When something changes unexpectedly, no one can say who did it or why.
Why it happens
Early on, the team is small and trust is high, so careful access feels like bureaucracy. As the team grows, the original arrangement quietly becomes the rule. Nobody owns the task of reviewing access.
What it costs
Wide permissions increase the chance of accidental changes and widen the blast radius of a stolen account. Shared logins destroy accountability, since the audit log shows the same name for everyone. Without visibility, investigating an incident takes far longer.
How to prevent it
Individual accounts
Give every person their own login so the history is meaningful and access can be removed cleanly.
Least privilege
Allow most people to view flags and change non-production environments, and reserve production changes for a small group.
Approvals and scheduling
Where your edition offers them, require approval for production changes and schedule risky ones for planned times.
Audit log and notifications
Read the audit log when things change unexpectedly, and send changes to a chat channel for everyone to see.
Regular access reviews
Every quarter, review the list of users and keys, and remove anyone who no longer needs access.
Strong sign-in
Enable multi-factor authentication and single sign-on if your plan supports them.
Loose permissions are like giving every employee a master key to the building because cutting separate keys seemed fussy. It works until the night something goes missing, and nobody can tell who was inside, or who had access in the first place.
Finer roles, approvals and single sign-on may depend on your plan or edition. Check what your plan includes, and compensate with process, such as a chat announcement rule, where a feature is missing.
18Mistake: Weak Testing of Flagged Code
Every flag doubles the paths through your code. Teams that test only the happy path meet the other path in production.
What it looks like
The new code is tested thoroughly with the flag on. Nobody tests with the flag off, because that is “the old code which already works”. After a change elsewhere, the off path quietly breaks. When the flag is switched off to roll back a problem, the rollback itself fails. In another variation, tests depend on the live flag service, so they pass one day and fail the next because someone changed a flag in the dashboard.
Why it happens
Testing effort follows attention, and attention goes to the new feature. The off path feels like a given. Making tests independent of the live service takes a little setup that is easy to skip.
How to prevent it
Test both states
Write checks for the flag off and the flag on, so rolling back is as safe as rolling forward.
Control flags in tests
Replace the real flag service in tests with a simple stand-in that returns the state the test needs.
Test the fallback
Simulate the flag service being unavailable and confirm the application uses its safe default.
Test the invalid value
Supply a missing or unexpected value and confirm the application stays safe.
Rehearse in real environments
Use development and staging in Flagsmith for end-to-end checks, and keep test traffic away from shared flags.
Testing only the flag-on path is like inspecting only the new bridge and never checking that the old bridge is still open. When the new bridge needs to close for repairs, drivers discover that the old one has been blocked for months.
Routing every flag read through a single small wrapper makes all of these tests easier, because you replace one thing in one place.
19Mistakes When Self-Hosting Flagsmith
Running Flagsmith yourself gives control and also adds chores. Most self-hosting troubles come from skipping the chores.
No tested backups
The database holds every flag, segment, user and audit entry. A team sets up automated backups and feels safe, but never restores one. When a disk fails or a command removes the wrong data, the backup turns out to be incomplete, unreadable or too old. A backup that has never been restored is only a hope. Schedule backups, store them away from the main system, encrypt them and rehearse the restore regularly, writing down how long it takes.
Database in a throwaway container with no protection
For convenience, the database runs in a container with its data on temporary storage, or on a local folder with no copies. A routine cleanup removes the storage, and everything vanishes. For production, prefer a managed database or a carefully operated one with automated backups and a standby, and keep the data on storage that survives container replacement.
Using the latest tag in production
The container configuration says to pull the newest image. A restart on an ordinary day brings in a new version with changes nobody tested, perhaps including database changes that cannot easily be undone. Pin an exact version, test upgrades in staging and change the version only on purpose.
Forgetting the background worker
Webhooks, audit processing and analytics rely on background work. In larger setups this runs in a separate task processor. If that worker stops, the dashboard still works and flags still evaluate, so nobody notices. Webhooks silently stop and records fall behind. Include the task processor in monitoring and alerts, and make sure it has permission to reach the outside addresses it needs.
Exposing the database or the application directly
For convenience, the database port is published to the internet, or the application is reachable without a reverse proxy and HTTPS. Automated scanners find open ports within hours. Keep the database on a private network, expose only a properly configured reverse proxy, and test from outside to confirm.
Skipping upgrades
Because nothing seems broken, upgrades are postponed month after month. Security fixes are missed, and the eventual jump to a modern version becomes large and risky. Upgrade in small, regular steps: read the release notes, back up, test in staging, migrate in a controlled step, replace containers gradually and keep the backup as the rollback tool.
| Mistake | What goes wrong | Better habit |
|---|---|---|
| Untested backups | Recovery fails when needed | Rehearse restores and record the time taken |
| Unprotected database storage | One cleanup erases everything | Managed database or protected volumes with off-site copies |
| Latest tag in production | Surprise versions after restarts | Pinned versions, tested in staging first |
| Unmonitored task processor | Webhooks and audits fail silently | Monitor backlog, age and failures; alert on silence |
| Public database port | Attacks within hours | Private networks and a single public proxy |
| Skipped upgrades | Security gaps and risky big jumps | Small, regular, rehearsed upgrades |
| Single machine for everything | One failure stops the service | Several copies across zones with a database standby |
Self-hosting without these habits is like owning a house and never checking the roof, the boiler or the smoke alarms. Everything seems fine for years. Then a single winter storm shows exactly which chores were skipped, all at once.
Free to download does not mean free to run. The cost of self-hosting is mostly the steady attention you give it. If you cannot commit that attention, the hosted service may be the more honest choice.
20Mistakes with Webhooks and Integrations
Webhooks tell other systems when flags change. They are helpful, and they have their own classic pitfalls.
No signature check
A receiver accepts any message sent to its address. A stranger who discovers the address can forge messages claiming that flags changed, triggering cache wipes, deployments or alerts. Configure a secret, verify the signature over the raw message body, use a constant-time comparison and reject anything that does not match.
Doing slow work before replying
The receiver tries to complete all its work, including calls to other services, before answering. The sender times out, retries, and the receiver now handles the same message twice. Verify, store the message safely, reply quickly with a success code and do the real work in the background.
Assuming exactly once, in order
Deliveries can arrive more than once, late or out of order. Receivers that add one to a counter, or overwrite state with whatever arrived last, drift into error. Make actions safe to repeat, compare timestamps inside messages and periodically reconcile with the real state from the Flagsmith interface.
Staying silent when it breaks
When a webhook pipeline fails, nothing visibly happens, which feels like peace. A cache stays stale or an audit archive misses a week. Monitor message volume, errors and backlog, alert when expected messages stop arriving, and consider a scheduled harmless test change as a heartbeat.
Wiring a message straight to a dangerous action
A webhook triggers a deployment or a deletion directly. If a message is forged, duplicated or delayed, a small mistake becomes an outage. Put a safety check between the message and any destructive action, and re-read the real state before acting.
Verify every message
Use a secret and check the signature on the raw body before doing anything else.
Reply fast, work later
Store the message durably, answer at once and process in a background worker.
Be idempotent
Design actions so that handling a message twice has the same effect as handling it once.
Reconcile regularly
Compare your systems with the real state in Flagsmith on a schedule, and repair differences.
A webhook receiver that trusts every message is like a mailroom that delivers any envelope claiming to be from the managing director. Verification, a quick receipt and a log of what was handled keep the mailroom honest.
If a built-in integration covers your tool, it may save you from building and securing your own receiver. Check what exists for your plan before writing custom code.
21Mistakes in Archiving and Migration
Ending a flag’s life, or moving a whole setup elsewhere, are moments when small oversights have large effects.
Archiving a flag that is still asked for
A person archives a flag that looks finished, but a running application still asks for it. The application now receives no answer for that flag and falls back to its default. If the default is wrong, behaviour changes suddenly for some users. Mobile apps are the classic case, because old versions stay on phones for months. Remove the code, deploy, confirm via logs or monitoring that nothing asks for the flag, and only then archive.
Deleting in a hurry during cleanup
A cleanup day turns into a mass deletion. Flags that look stale are removed without checking owners or code. One of them guarded a rarely used but important path. Clean up in small batches, with owners consulted and the audit log checked.
Migrating without a plan for keys and identities
When moving between the hosted service and a self-hosted installation, or between organisations, teams often assume everything moves automatically. In reality, environment keys change, so every application needs updating. Identity data and history may not travel the way configuration does. Read what your chosen method moves, rehearse the migration in a test environment and move applications in stages with a rollback plan.
Forgetting to keep an export
Nobody keeps a human-readable copy of the flag configuration outside the database. After a serious loss, rebuilding by memory takes days. Take regular exports through Flagsmith’s own interfaces and store them safely.
flowchart TD
A["Decide to retire a flag"] --> B["Search all code and active app versions"]
B --> C{"Anything still asks for it"}
C -- Yes --> D["Wait or update those apps first"]
D --> B
C -- No --> E["Remove flag checks and old code path"]
E --> F["Deploy and watch monitoring"]
F --> G{"Any requests for the flag in logs"}
G -- Yes --> D
G -- No --> H["Archive the flag in Flagsmith"]
H --> I["Record the retired name"]
Reading the retirement path
The path begins with a search across all code and all active versions of every application. If anything still asks for the flag, you wait or update those applications first. Only when nothing asks do you remove the checks and the old path, deploy, and watch the monitoring. If logs still show requests for the flag, you go back. Only after a quiet period do you archive the flag, and you record its name so that nobody reuses it.
Retiring a flag is like closing a railway station. You check that no timetable still lists it, no train is scheduled to stop there and no passengers are waiting. Only then do you lock the doors and remove the signs, and you keep the records in case someone asks what stood there.
22Team and Process Mistakes
Many flag problems are not technical. They come from how teams talk to each other, or fail to.
No owner
Flags are created by individuals and used by teams, yet nobody owns them. When a flag misbehaves, each team assumes another team will handle it. Give every flag a named owner, and record the owner in the description.
No shared language
Teams use different names for the same flag, different words for environments and different expectations for what on means. Agree a vocabulary, a naming style and a short guide, and use the exact flag name in tickets, release notes and chat.
Changes without announcements
Someone changes a production flag and tells no one. A colleague, chasing a bug, spends hours before discovering that a flag changed an hour earlier. Post production changes to a shared channel with the flag name, environment, person and reason. The audit log records the facts, but a message in the channel tells people at the moment they need it.
No rehearsal of emergencies
Kill switches exist, yet the team has never practised using them. During a real incident, people hesitate over which flag to change, whether they have permission and how long it takes to take effect. Rehearse kill switches in a calm moment, write short instructions and check the timing.
No regular review
Nobody schedules time to tidy flags, review access or check settings. Problems accumulate silently. A short monthly review of flags, users, keys and alerts costs less than one bad incident.
Owners on every flag
A named person, recorded in the description, who answers questions and decides when to retire it.
Announce production changes
A short, consistent message in a shared channel every time production flags change.
Practise the emergency
Rehearse kill switches and time their effect before you need them.
Review monthly
Fifteen minutes on flags, users, keys and alerts catches drift while it is small.
Teams that never rehearse emergencies are like offices that have fire extinguishers but never hold a fire drill. The equipment is in place, yet when the alarm sounds, people argue about where the exits are and which extinguisher to grab.
Write a one-page flag charter covering naming, owners, environments, announcements, cleanup and emergencies. A short, agreed document prevents long, repeated discussions.
23How One Small Mistake Becomes an Incident
Serious incidents are rarely caused by one error. They happen when several small weaknesses line up. Let us watch it happen in slow motion.
sequenceDiagram
participant E as Engineer
participant D as Dashboard
participant P as Production Servers
participant C as Customers
participant S as Support
E->>D: Open flag from a chat link
Note over E,D: Link opens Production, not Staging
E->>D: Toggle checkout_new_payment_form OFF
D-->>E: Change saved, no approval needed
D->>P: New state available to SDKs
P->>P: Some servers refresh now, others after cache expires
P-->>C: Customers see a mix of old and new checkout
Note over P,C: Old path was never tested after recent change
C->>S: Reports of failed payments
S->>E: Asks what changed
E->>D: Checks audit log, finds own change
E->>D: Toggle back ON
P-->>C: Behaviour settles after caches refresh
Reading the chain
The story starts with a link in a chat message that opens production rather than staging. The engineer toggles a flag, intending to test the old checkout path. Nothing stops the change, because production changes need no approval. The new state spreads to servers at different times, since each refreshes on its own schedule, so customers see a confusing mixture. The old path, which has not been tested since a recent change, turns out to be broken, so payments fail. Support asks what changed, and the engineer finds the answer in the audit log, toggles the flag back, and waits for the caches to settle.
Count the weaknesses: a look-alike environment, a missing approval, an untested off path, a mixed refresh timing, no announcement and slow discovery. Fix any one of them and the incident is smaller or disappears. Fix several and it never happens.
This is the Swiss cheese idea of safety. Each safeguard is a slice of cheese with holes. A single slice never stops every error, but when several slices are stacked, the holes rarely line up. Every habit in this guide is one more slice.
Slices you can add
| Weakness in the story | Slice that would have helped |
|---|---|
| Link opened the wrong environment | Distinct environment names and a habit of checking before clicking |
| No approval for production | Change requests or a second-person rule |
| Old path untested | Tests for both flag states, run on every change |
| Servers refreshed at different times | Known, short refresh intervals for important flags |
| No announcement | Automatic notification of production changes to a team channel |
| Slow discovery | Audit log as the first stop in every incident |
24A Diagnostic Path When Something Looks Wrong
When a flag misbehaves, the first minutes matter. A fixed order of questions beats guesswork.
flowchart TD
A["Something looks wrong with a flag"] --> B["Check the audit log for recent changes"]
B --> C{"A relevant change found"}
C -- Yes --> D["Confirm environment and who changed it"]
D --> E["Decide: revert the change"]
C -- No --> F{"Is the app reading the right environment key"}
F -- No --> G["Fix the key and redeploy"]
F -- Yes --> H{"Does the flag name match exactly"}
H -- No --> I["Correct the spelling"]
H -- Yes --> J{"Do identity or segment overrides apply"}
J -- Yes --> K["Review override and priority order"]
J -- No --> L{"Could a cache be hiding the change"}
L -- Yes --> M["Wait for refresh and verify again"]
L -- No --> N{"Can the app reach Flagsmith"}
N -- No --> O["Fix network, address or certificate; confirm defaults"]
N -- Yes --> P["Check service health and escalate"]
Reading the path
Always begin with the audit log, because the most likely cause of a surprise is a recent change. If a relevant change exists, confirm the environment and the person, and decide whether to revert. If not, check that the application reads the right environment key, then that the flag name matches exactly. Next consider overrides: a rule for the identity or a segment may explain why one user sees something different from another. Then think about caches, which may simply be showing an older answer. Then check connectivity: if the application cannot reach Flagsmith, it is using defaults. Only after these steps should you suspect the service itself.
This is like a doctor’s routine. Check the vital signs first, ask about recent changes, then work from the most common causes to the rarest. Doctors who start with exotic theories miss the ordinary infection, and engineers who start with exotic theories miss the misspelled name.
Pin this path where your on-call team will see it. In a stressful moment, a clear order of questions is worth more than cleverness.
25A Prevention Checklist
Use this checklist at the start of a project, before a big release and during your regular reviews.
At the dashboard
- I have read the environment name before clicking.
- The flag has a clear name, a useful description, an owner and an end date.
- I am changing one thing at a time, and I have told the team about production changes.
In the code
- Every flag read has a safe default and goes through one wrapper.
- Keys are of the right type, stored safely and tied to the right environment.
- No secrets or unnecessary personal data appear in values or traits.
- Identities are stable and opaque.
- Tests cover flag off, flag on, service unavailable and invalid values.
In the rollout
- The rollout plan lists steps, signals and thresholds.
- Someone is watching, and someone knows how to turn the flag off.
- The refresh timing of every application has been measured.
In the team
- Production changes are limited, approved where possible and announced.
- The audit log is the first stop in incidents.
- Kill switches have been rehearsed.
- Flags are reviewed monthly and retired promptly.
In operations, if self-hosted
- Images are pinned and mirrored, and upgrades are regular and rehearsed.
- The database is protected, backed up and restored in drills.
- The task processor is monitored, and alerts cover silence as well as errors.
- Only the reverse proxy is public.
Signs of a healthy setup
- Every flag has an owner and a purpose you can state in a sentence.
- Few flags are older than their planned end date.
- Production changes appear in a team channel within seconds.
- The team has timed their kill switch.
- Restores and upgrades are routine, not events.
Warning signs
- Flags nobody can explain.
- Shared logins and wide administrator access.
- Applications that break when Flagsmith is unreachable.
- Backups that have never been restored.
- Surprise discoveries of what changed during incidents.
A checklist is the pilot’s pre-flight walk-around. The aircraft looks perfect from the cockpit, yet the pilot still checks the tyres, the fuel and the control surfaces. These few minutes of dull inspection are what make flights uneventful.
26Lessons from the Wider Software World
Flag mistakes are not unique to Flagsmith, and not unique to small teams. Large, careful organisations have met the same problems.
The trading firm and the reused flag
A widely told cautionary tale describes a trading firm that lost an enormous sum within minutes after a deployment reached only some of its servers, and a reused flag name reactivated old code on the others. The lesson is threefold: never reuse a flag name, remove dead code and make deployments consistent across all servers.
Streaming services and practised failure
Netflix became known for deliberately breaking parts of its own systems to prove that the rest keeps working. The lesson for flags: do not assume your fallback path works. Block the flag service on purpose in a safe environment, and watch what your applications do.
Code hosting platforms and gradual change
Platforms such as GitHub have described running new systems quietly behind flags, comparing results with the old ones before users notice. The lesson: a flag lets you rehearse a change with real traffic, but only if you watch the results and keep the exit ready.
Cloud providers and blast radius
Large cloud providers publish post-incident reviews that repeatedly mention limiting the blast radius of a change: release to a small area, observe, then widen. The lesson for flag users is the same. A percentage rollout is a tool for shrinking the blast radius, and it only works if you use it.
Secret leaks in public repositories
Many companies have suffered incidents when access keys were committed to public code repositories and found by automated scanners within minutes. The lesson: treat any committed key as leaked, rotate it at once, and keep secret keys out of code from the start.
These examples summarise widely discussed industry stories, and details change over time. Treat them as illustrations of practice, not as exact historical records.
27Mistakes with Percentage Rollouts and Experiments
Percentage rollouts feel mathematical and therefore safe. In practice they hide several traps that catch careful teams.
Mistake: reading too much into a tiny sample
A team enables a feature for one percent of users, sees no complaints after an hour, and declares success. But one percent of a small audience may be a handful of people, and an hour may not include the busiest moments, the unusual devices or the rare but costly actions. Silence is not evidence when almost nobody was looking. Decide in advance how many users and how much time you need before the next step, and write the numbers in the rollout plan.
Imagine tasting one spoonful of soup from a huge pot that has not been stirred. If the spoon came from the top, you learn about the top only. A sample is useful only when it is large enough and taken from places that represent the whole pot.
Mistake: forgetting that the split depends on the identity
Flagsmith places each identity into a bucket in a stable way, so the same person receives the same answer each time. That is a good thing, but it means a percentage only works when identities are stable. If your application sends a fresh random identifier on every visit, the same person is shuffled in and out of the feature, and the experience flickers. If you send no identity at all, the percentage rule may not behave as you expect. Always check how your application identifies visitors before relying on a split.
Mistake: moving the percentage down and up carelessly
Lowering a rollout from fifty percent to ten percent removes the feature from most people who had it. Raising it again later may bring back some of those people, but you should not assume it brings back exactly the same ones. For users who had already stored data created by the new feature, a sudden removal can cause confusing screens. When you reduce a rollout, think about what those users have already done with the feature, and whether the old path can handle their data.
Mistake: running two experiments that overlap
If two flags both change the checkout page, a user may land in both groups at once. Any change in sales could belong to either experiment, or to the combination. Teams then argue about results that cannot be separated. Keep a simple calendar of running experiments, avoid overlapping changes on the same screen and name the experiment owner on each flag.
Mistake: judging by the wrong measure
A new button may be clicked more often, yet lead to fewer completed purchases. Choose the measure that reflects the real goal before the experiment starts, not after you see which number looks best. Choosing the measure afterwards is like drawing the target around the arrow once it has landed.
Some experiment and analytics features depend on your Flagsmith edition and on the analytics tools you connect. Confirm what your plan includes before promising results to colleagues.
| Trap | What to do instead |
|---|---|
| Tiny early sample | Agree user count and duration before each step |
| Unstable identity | Use one stable identifier for each person or device |
| Careless reductions | Check what users did with the feature before shrinking |
| Overlapping experiments | Keep a calendar and avoid shared screens |
| Measure chosen afterwards | Write the success measure in the plan first |
28Mistakes with Mobile Apps, Plans and Costs
Mobile applications and growing usage bring their own surprises. Both are easy to overlook until they hurt.
Mistake: forgetting that old app versions live on
A website updates for everyone the moment you deploy. A mobile app does not. Thousands of people keep running old versions for months. If you remove a flag from the dashboard or change what its values mean, those old versions still ask for it. They may receive nothing, fall back to their defaults, or misread a new value. Before changing or retiring a flag used by mobile apps, find out which app versions still exist and what they expect.
Think of printed menus. You can change the kitchen overnight, but menus already handed to customers still list the old dishes. A flag used by an old app version is a menu you can no longer collect.
Mistake: depending on a fresh network connection
Phones go into tunnels, lifts and aeroplane mode. An app that needs a fresh answer before drawing its first screen will feel broken on a weak connection. Let the app start with stored answers from its last successful visit, or with sensible defaults, and update quietly in the background. Decide deliberately whether a change should take effect at once while the user is looking, or at the next launch, since changing a screen under someone’s thumb can be jarring.
Mistake: asking too often
Some teams, wanting quick updates, set very frequent refreshes on every device. Multiplied by a large user base, that produces a flood of requests, draining batteries, using mobile data and raising the bill or the load on your own servers. Choose a refresh rhythm that matches how quickly you genuinely need changes to spread. Most flags do not need second-by-second freshness; the few that do, such as emergency switches, can be treated specially.
Mistake: ignoring plan limits until they bite
Hosted plans usually include limits, such as numbers of requests, projects, team members or features. A product that suddenly becomes popular can pass a limit unexpectedly, and the consequences depend on the plan. Learn your limits, watch your usage and decide who is told when you approach them. For self-hosted setups, the equivalent surprise is capacity: the database and servers must grow as traffic grows.
Mistake: treating cost as someone else’s problem
Every extra environment, every duplicated project and every over-eager refresh has a price in money, attention or both. A short quarterly review that asks which projects are unused, which environments are idle and which applications make the most requests often finds easy savings.
Keep a small table of every application that reads flags, with its platform, its oldest supported version and its refresh behaviour. When you change a flag, you will know instantly who might be affected.
Old versions
Know which versions still run before changing or retiring a flag.
Stored answers
Start from saved values and refresh quietly in the background.
Sensible refresh
Match the refresh rhythm to how fast you truly need changes.
Regular review
Prune idle projects and environments and watch plan limits.
29Glossary of Terms
Every important word used in this guide, in plain language, for quick lookup.
| Term | Plain meaning |
|---|---|
| Feature flag | A named switch outside the code that turns a feature on or off without a release. |
| Environment | A separate copy of the world, such as development, staging or production, with its own flag states and keys. |
| Environment key | A code that tells an SDK which environment’s flags to read. |
| Client-side key | A key meant for browsers and mobile apps that can only read flags. |
| Server-side key | A secret key for trusted servers that unlocks extra abilities such as local evaluation. |
| Management key | A secret key that can change configuration through the management interface. |
| SDK | A ready-made code library that lets an application talk to Flagsmith. |
| Default value | The answer your code uses when it cannot obtain one from Flagsmith. |
| Identity | One specific user known to Flagsmith, identified by an ID from your application. |
| Trait | A small fact about an identity, such as plan or country, used for targeting. |
| Segment | A saved group of users defined by rules on their traits. |
| Override | A setting that gives a flag a different state or value for a segment or identity. |
| Percentage rollout | Enabling a feature for a chosen share of users, stable for each user. |
| Kill switch | A flag used to turn off a risky or costly feature quickly. |
| Cache | A short-term memory of recent answers that avoids repeated questions. |
| Local evaluation | Letting a server SDK hold the rules and decide flags without a network call. |
| Flag debt | The accumulated cost of flags and dead code that have outlived their purpose. |
| Blast radius | The number of users or systems affected when something goes wrong. |
| Audit log | A diary of who changed what and when in Flagsmith. |
| Webhook | An automatic message Flagsmith sends to another system when something changes. |
| Idempotent | Safe to repeat: doing it twice has the same effect as doing it once. |
| Reconciliation | A periodic check that compares your systems with the real state and repairs differences. |
| Task processor | The background worker in a self-hosted setup that runs jobs such as webhooks and audit processing. |
| Archive | Removing a finished feature from the active list while keeping its history. |
30Frequently Asked Questions
Short answers to the questions people ask most often about avoiding flag mistakes.
31Summary and Key Takeaways
Everything in this guide comes down to a handful of ideas you can carry into your next release.
Feature flags make software safer, but only when the habits around them are sound. The most common mistakes are not exotic. They are acting in the wrong environment, leaving out defaults, mishandling keys, storing secrets in values, never removing flags, reusing names, rolling out too fast and ignoring operations. Each has a simple, cheap remedy, and the remedies stack: every habit adds another slice of protection, and incidents need many holes to line up at once.
Key Takeaways
- Check the environment every time. Read the environment name before clicking, limit production access, use approvals where available and announce production changes.
- Always have a safe default. Route flag reads through one wrapper, define a default for every flag, use short timeouts and test the case where Flagsmith is unreachable.
- Treat keys and values with care. Use client-side keys only in clients, keep server and management keys secret, rotate leaked keys and never store secrets or needless personal data in flags.
- Name, own and retire every flag. Use clear names, write the owner and end date in the description, never reuse a name and remove finished flags and their old code.
- Keep flags simple and identities stable. One flag should answer one question, segments should have deliberate priorities and identities should be stable and opaque.
- Roll out gently and know your timing. Move from staff to small percentages to everyone while watching agreed signals, and measure how long a change takes to reach each application.
- Operate with discipline. Test both flag states, rehearse kill switches, read the audit log first in incidents and, if self-hosting, keep tested backups, pinned images, monitored workers and regular upgrades.