The Default Value in Flagsmith

The Default Value in Flagsmith

The answer a flag gives when nothing more specific applies, and the answer your application falls back on when no answer arrives at all. Learn the four places a default lives, how they differ, and how to choose each one so that surprises become boring.

Picture a hotel night receptionist. When a guest arrives with a booking, the receptionist gives the room that was reserved. When a guest arrives with a special request, such as a quiet room, the receptionist follows the request. But what if the computer system is down and nobody can find a reservation? The receptionist does not freeze. There is a plan: a standard room, a standard rate, and a note to sort it out in the morning. That plan, decided long before the emergency, is a default.

Software needs exactly the same kind of plan. A feature flag answers questions such as “should this screen be shown?” or “how many results should we display?” Most of the time Flagsmith answers according to rules. But sometimes no rule matches, or the answer cannot be fetched, or the flag does not exist. In each case something must still happen, and what happens is the default value. Choosing defaults badly is one of the quietest ways to cause an outage. Choosing them well is one of the cheapest ways to prevent one.

This guide explains every kind of default in Flagsmith from the ground up. No previous knowledge is assumed. Each new word is explained when it first appears, and each idea comes with a picture from everyday life.

1What Does “Default Value” Mean in Flagsmith?

The phrase is used in several ways, and mixing them up is the number one source of confusion. This chapter separates them.

First, the basics

A feature flag is a switch inside software that decides whether a behaviour is active. Flagsmith is a platform that stores those switches, lets people change them from a dashboard, and delivers the answers to applications through small libraries called SDKs. A value is an optional piece of information that a flag can carry along with its on or off state, such as a number or a short piece of text. That is called remote configuration.

The word “default”

A default is the answer used when no more specific answer exists. In everyday life, the default font in a document is what you get if you do not choose another one. In Flagsmith there are four distinct defaults, each living in a different place and used at a different moment.

Meaning 1

The creation default

The starting state and value you set when you first create a feature. It decides what every Environment begins with.

Meaning 2

The Environment default

The baseline answer of a feature inside one Environment, used for everyone who matches no segment or personal override.

Meaning 3

The control value

For features that split users between versions, the original value that people receive when they are not placed in any variation.

Meaning 4

The default in your code

The fallback your application uses when Flagsmith gives no answer at all, because of a network failure or a missing flag.

Everyday analogy

Think of a restaurant. The recipe card in the kitchen says how a dish is normally made. That is like the creation default. The standing house rule says “unless the customer asks otherwise, serve it medium”. That is like the Environment default. If the order slip is lost entirely, the waiter serves the house special, which is like the default in code. Four levels, four different moments, one shared idea: what happens when nothing more specific is known.

i
Remember this

When someone says “the default” in a team meeting, ask which one they mean. The creation default and the default in code can be completely different answers for the same flag, and many bugs hide in that gap.

2Why Defaults Deserve Careful Thought

Defaults rarely get attention, because when they work nobody notices. They matter most on the days everything else is going wrong.

The problem defaults solve

Every system must decide what to do in situations nobody planned for. A flag platform is a network service, and network services are sometimes slow, sometimes unreachable and sometimes asked for things that do not exist. If your application has no plan for these moments, it will invent one by accident: it may crash, it may show a blank screen, or it may quietly turn a feature on that should have been off. A deliberate default turns an unpredictable accident into a predictable, harmless behaviour.

A principle older than the internet

In 1975, two computer scientists, Jerome Saltzer and Michael Schroeder, published a famous paper on protecting information in computer systems. One of their design principles is called fail-safe defaults. It says that when something goes wrong or is unspecified, the system should lean towards the safe outcome rather than the permissive one. A door that cannot reach its lock controller should stay locked, unless it is a fire exit, in which case it should open. The principle is not “always choose off”. It is “choose the answer that causes the least harm”.

A good default is a decision made calmly, so you do not have to make it in a panic.
Everyday analogy

Lifts are built so that if the power fails, the brakes clamp shut rather than release. Nobody asked the lift in the middle of the emergency what to do. The engineers decided years earlier, in a quiet office, which direction failure should lean. Your flag defaults are the brakes of your product.

What big companies teach us

Engineering teams at companies such as Netflix and Amazon have spoken publicly about designing for failure: assuming that any dependency can be slow or unavailable and making sure the customer still gets a reasonable experience. Netflix is widely known for the idea that a missing recommendation row should never stop a video from playing. A flag lookup is one more dependency. If it fails, the product should drop back to a calm, known behaviour and carry on.

4
places a default can live
1
default is used at any moment
0
defaults should be accidental

The cost of an unthought default

An unthought default rarely announces itself. It sits quietly in the code for months, and then one afternoon a network problem or a typo causes it to be used. The cost is not the moment of failure but the confusion afterwards: the team asks why customers saw something nobody planned, and nobody can say who decided it. Writing the decision down in advance, even in one sentence, turns that confusion into a lookup. The effort is small, the benefit arrives on the worst day of the year, and that is the best kind of engineering trade.

3The Map: How the Four Defaults Fit Together

A picture of the whole journey makes each individual default easier to place.

Follow a feature from the moment it is created to the moment a user sees its result. The creation default sets the starting state. Each Environment then holds its own baseline, which is the Environment default. Segment and identity overrides may change the answer for chosen people. And if the application cannot obtain an answer, it uses the default written in its own code.

flowchart TD
  A["Feature created with a creation default"] --> B["Each Environment holds its own baseline value"]
  B --> C{"Does the user have an identity override?"}
  C -- Yes --> R1["Answer: identity override"]
  C -- No --> D{"Does the user match a segment override?"}
  D -- Yes --> R2["Answer: segment override"]
  D -- No --> R3["Answer: Environment default"]
  R1 --> E["SDK delivers the answer to the app"]
  R2 --> E
  R3 --> E
  E --> F{"Did an answer arrive?"}
  F -- Yes --> G["App uses the answer"]
  F -- No --> H["App uses the default written in its code"]
    
Fig 1. From creation to use: the places a default can come from.
DefaultWhere it livesWhen it is usedWho sets it
Creation defaultThe feature creation form in a ProjectWhen the feature is first madeThe engineer creating the feature
Environment defaultThe feature state inside one EnvironmentFor everyone matching no overridePeople with permission for that Environment
Control valueThe feature’s original value, in a split featureFor users not placed in a variationThe team running the experiment
Default in codeYour application’s source codeWhen no answer arrivesThe developers of the application
!
Key insight

The first three defaults live inside Flagsmith, and a person can change them in the dashboard. The fourth lives in your code, and only a new release can change it. That difference in who can change what, and how fast, explains most of the advice in this guide.

Which default answers which question?

A quick way to keep the four straight is to attach a question to each. The creation default answers “what should this feature start as?” The Environment default answers “what is the general rule in this stage?” The control value answers “what does the ordinary user get while an experiment runs?” The default in code answers “what do we do if nobody answers at all?” If you can state which question you are asking, you almost always know which default you mean.

4Meaning One: The Creation Default

When you create a feature, Flagsmith asks what it should start as. That small decision is copied into every stage at once.

What you decide at creation

When creating a feature in a Project, you give it a name and a description, and you typically choose whether it should be enabled or not by default, and, for features that carry a value, what that starting value is. Because a feature’s definition is shared across the whole Project, Flagsmith needs to put a state into every Environment, and by default it uses what you entered on the creation form.

The effect on every Environment

If you create a feature and choose to enable it by default, then Development, Staging and Production can all receive the feature switched on. That may be exactly what you want for a harmless setting. It is a serious problem for a new, untested checkout page, because the moment the feature is created, real customers in Production could see it.

graph TD
  FORM["Creation form: enabled by default = yes, value = 20"] --> DEV["Development: enabled, value 20"]
  FORM --> STG["Staging: enabled, value 20"]
  FORM --> PRD["Production: enabled, value 20"]
    
Fig 2. A creation default can spread to every Environment, including Production.

A safety setting at the Project level

Because this behaviour can surprise people, many versions of Flagsmith offer a Project setting, often described as preventing flag defaults. When it is switched on, the starting state and value entered at creation are not spread across all Environments, which keeps new features switched off in places where nobody chose otherwise. The exact wording and availability may differ in your version, so open your Project settings and read the description there before relying on it. If it exists in your version, switching it on is one of the quickest safety wins in the whole product.

Everyday analogy

Imagine a chain of shops that decides its new seasonal menu with one form sent to every branch. If the form says “start selling today”, every branch starts at once, including the one whose staff have not been trained. A careful head office writes “available from the date each branch confirms”, so the decision stays local. The Project safety setting does the same for new flags.

✓
Safe habit

Create new release flags disabled. Enable them first in Development, then Staging, and only then in Production, one deliberate click at a time. Creation should never be the same event as release.

A short story of a creation default gone wrong

Imagine an engineer creating a flag for an unfinished loyalty page. In a hurry, they tick the option to enable it by default. Because the feature definition is shared by every Environment, Production receives the flag in the enabled state a moment later. The page code is deployed and waiting, so real customers suddenly see half a page. Nothing was “flipped” in Production by any person. The creation form did it. Stories like this are why many teams treat creation as a safe, boring event, and keep every real decision for the later, deliberate step of enabling the flag in each Environment.

5Meaning Two: The Environment Default

This is the default most people mean in daily work: the baseline answer a feature gives inside one Environment.

What it is

Inside each Environment, every feature has a feature state: whether it is enabled, and, if it carries one, its value. That state is the Environment default. It is the answer given to anyone who does not match a segment override or an identity override. Think of it as the general rule for that stage, with overrides as the exceptions.

Why it is the most important default

For most users, the Environment default is the answer. If only staff and a pilot group have overrides, then everyone else, perhaps ninety-nine percent of customers, simply gets the Environment default. Changing it changes the experience of nearly everybody at once. That is why it deserves the strongest protection in Production.

Rollout stageEnvironment defaultOverridesWho sees the feature
HiddenOffNoneNobody
Staff trialOffStaff segment onEmployees only
Ten percentOffStaff and ten percent segments onEmployees and a small slice of customers
Full releaseOnNone neededEveryone

Notice the shape of a classic rollout: the Environment default stays off while overrides grow the audience, and the very last step is to change the default itself to on. Because that last step affects everyone, it is the one to take most carefully and to announce in your team channel.

Everyday analogy

A school has a general rule that phones stay in lockers. The rule is the Environment default. A teacher may allow phones for a project, and a doctor’s note may allow one pupil a phone for health reasons. These are overrides. Changing the general rule changes life for every pupil at once, so it is the decision the head teacher takes most seriously.

The value half of the default

For features that carry a value, the Environment default includes that value. A search feature may be enabled with the value “twenty” in Production and “five” in Development, so test runs stay small and quick. Each Environment keeps its own copy, so changing the value in one never touches another.

!
Watch out

Because Environments hold separate copies, they can drift apart. Before every launch, compare Staging and Production side by side. A default that differs where you did not intend is a bug waiting for a busy day.

Reading defaults in the dashboard

In the feature list, each row typically shows the current state for the Environment you are looking at, along with a hint when overrides exist. Make it a habit to open the same feature in two Environments side by side, and compare the state and the value. If you only ever look at one Environment, drift can grow unseen. A good time for the comparison is the day before a launch, and again straight after any incident in which values were changed by hand.

6Meaning Three: Defaults for Values and Remote Configuration

A flag can carry more than yes or no. When it carries a number or a piece of text, the question of a good default becomes richer.

What is a value?

A value is information attached to a feature, such as a whole number, a piece of text or a true or false answer. Using values lets teams change settings of a running application without releasing new code. This is called remote configuration. Examples include the number of results on a page, the text of a banner, or the maximum size of an upload.

An empty value is also a value

A feature may have no value at all. Your code must handle that case sensibly. An application that expects a number and receives nothing might treat the missing number as zero, and zero can mean “show no results”, “allow no uploads” or, in some designs, “no limit at all”. The meaning of zero and of empty is one of the most common sources of surprise, which is why the next chapters spend time on it.

Type of valueExampleRisky defaultSafer default
Whole number, a limitMaximum results per pageZero, which may show nothingThe long-standing normal number, such as twenty
Whole number, a timeSeconds to wait for a partner serviceZero, which may mean never waitA sensible timeout such as five seconds
Text, a messageBanner wordingEmpty text, which shows a blank barNo banner at all, or a neutral standard message
Text, a choiceName of a payment providerEmpty, which may crash a lookupThe current trusted provider
True or falseAllow guests to check outTrue by accidentThe current business rule
Everyday analogy

A thermostat that loses its setting should return to a comfortable temperature, not to zero degrees and not to the maximum. A good default value for a number is the one that was already working before the flag existed.

Scenario: tuning a search page during a sale

An online retailer stores the number of search results as a remote configuration value, normally twenty. During a sale peak, the team lowers it to twelve in Production. In the application code, the default for this number is twenty, the long-standing normal. If Flagsmith were unreachable during the sale, the page would show twenty results, which is slower but safe, rather than showing zero or crashing. Writing the proven number in code is cheap insurance.

7Meaning Four: The Default in Your Own Code

This is the default that protects you on the worst day. It lives outside Flagsmith, in the application that asks the question.

What it is

When an application asks the SDK for a flag, three outcomes are possible. The SDK returns an answer. The SDK returns a built-in “nothing found” answer. Or the call fails. For the second and third outcomes, the application needs its own plan. The default in code, also called the fallback or safe default, is that plan. It is written by the developers and shipped inside the application.

How SDKs help

Most Flagsmith SDKs return a harmless built-in answer when a flag is missing or Flagsmith cannot be reached, typically “not enabled” for a flag and “no value” for a setting. Many SDKs also let you supply your own default flag handler, which is a small piece of logic that decides what to return in such cases, flag by flag. The exact behaviour differs between languages and versions, so read the notes for the SDK you use. The principle never changes: never leave this to chance.

1

The app asks for a flag

The code asks the SDK whether a feature is enabled, or what its value is.

2

The SDK tries to answer

It uses fresh data, cached data or a local copy of the rules, depending on its mode.

3

If it cannot, the default applies

Either the SDK’s built-in answer or your own handler supplies the value.

4

The code carries on

The application follows the default path, and the user sees a calm, known behaviour.

Everyday analogy

A pilot flying without a working weather report does not guess wildly. The airline has a standing procedure for exactly that case, written in advance and trained for. The default in code is that standing procedure for your application.

!
The quiet danger

When the default is used, nothing visibly breaks. The feature simply behaves as the default says. That silence is exactly why a wrong default can run unnoticed for days. Chapter 25 shows how to make default use visible.

Where to place defaults in the code

Resist the temptation to scatter defaults wherever a flag is used. A tidy approach is to collect every flag name and its default in one small section, often called a flag catalogue. The rest of the code asks the catalogue for a flag and receives both the live answer and, if needed, the fallback. This brings three advantages: names are written only once, a reviewer sees any default change in one place, and the unreachable test can exercise every default by switching the catalogue to fallback mode.

8Defaults in Split Features: The Control Value

When a feature splits users between versions, the word default takes a slightly different shape.

What is a multivariate feature?

A multivariate feature offers several possible values and divides users between them by percentage. It is the base of experiments. A button might say “Buy now” for some people, “Get it today” for others and “Add to basket” for the rest. Each alternative is called a variation.

The control

The original value of the feature is called the control. It is the version that people receive when they are not placed in any variation. Each variation is given a percentage of users, and whatever percentage remains unassigned falls back to the control. If two variations take twenty percent each, the control serves the remaining sixty percent. In this sense, the control is the default of an experiment.

GroupButton textShare of usersRole
ControlBuy now60 percentThe default, and the comparison point
Variation AGet it today20 percentFirst challenger
Variation BAdd to basket20 percentSecond challenger
Everyday analogy

A bakery tests two new loaves on a few customers each morning, while most customers still get the usual loaf. The usual loaf is the control. It stays the default, so a failed experiment never leaves anyone hungry, and it also gives the baker something fair to compare against.

Why a good control matters

If the control is the long-standing, well tested value, then an experiment that goes wrong harms only the small share placed in a variation. If the control itself is something untested, there is no safe place to retreat to. Always keep the proven version as the control, and move it only after a challenger has clearly won.

✓
Good habit

At the end of an experiment, make the winning value the new control, set the variations to zero, and then remove the experiment feature from your code. Leaving old variations behind creates confusion about which value is really the default.

Pitfalls with the control

Two mistakes recur. The first is editing the control value in the middle of an experiment. Everyone in the control group suddenly receives something different, and the comparison with the variations is spoilt. Decide the control before the experiment begins and leave it alone. The second is forgetting that the control also serves anyone left unassigned. If the variations take only ten percent between them, ninety percent of users, including all anonymous visitors, receive the control, so it must be an experience you are happy for most people to have.

9The Evaluation Order, with Defaults in Place

When several rules could apply, Flagsmith has a clear order. Knowing exactly where the default sits in that order removes most guesswork.

For one feature, in one Environment, for one person, Flagsmith works from the most specific rule to the most general. It checks for an identity override first, which is a rule for one exact person. Next it checks segment overrides, which are rules for groups, taking the highest ranked one that matches. If neither applies, the answer is the Environment default. Only if the application receives no answer does the default in code take over.

flowchart TD
  START["Question: value of feature X for person Y in Environment E"] --> Q1{"Identity override for Y?"}
  Q1 -- Yes --> R1["Use identity override"]
  Q1 -- No --> Q2{"Segment override that matches Y?"}
  Q2 -- Yes --> R2["Use highest ranked matching segment"]
  Q2 -- No --> R3["Use the Environment default"]
  R1 --> OUT["Answer returned"]
  R2 --> OUT
  R3 --> OUT
  OUT --> Q3{"Did the app receive it?"}
  Q3 -- No --> R4["Use the default in code"]
  Q3 -- Yes --> DONE["Use the answer"]
    
Fig 3. The most specific rule wins, and the default in code is the last line of defence.
ShopperIdentity overrideSegments matchedEnvironment defaultAnswer
Asha, staffNoneStaff, enabledOffOn, from the segment
Ben, ordinary customerNoneNoneOffOff, from the Environment default
Chloe, a new visitor with no accountNoneNone possibleOffOff, from the Environment default
Dev, staff with a known issueDisabledStaff, enabledOffOff, from the identity override
Everyday analogy

A library has a general loan period of three weeks. A student with a project gets six weeks, which is a group rule. A pupil with a doctor’s note gets twelve, which is a personal rule. The three weeks is what everyone else gets, and it is also what the librarian uses when the record of exceptions is lost.

A debugging ladder for a surprising answer

When a person sees an answer nobody expected, walk down the same ladder Flagsmith does. Do it in order, and write the finding at each step.

  • Which Environment was asked? Confirm the key belongs to the stage you think it does.
  • Was an identity sent? If not, only the Environment default can apply.
  • Is there an identity override? Look at the person’s page in the dashboard.
  • Which segments match? Check traits and their exact format, then the order of the segments.
  • What is the Environment default? Compare it with the answer received.
  • Did the answer arrive at all? If the answer matches none of the above, the application may have used its own default.

10Defaults for Anonymous Visitors and Missing Information

Many answers depend on who the person is. What happens when you do not know?

Identities and traits

An identity is Flagsmith’s name for one end user, usually represented by a user ID. A trait is a fact attached to an identity, such as “plan equals premium” or “country equals India”. A segment selects identities by their traits or by a percentage. These need information about the person to work.

When the person is unknown

A visitor who has not signed in has no user ID. If the application asks for the Environment’s flags without an identity, no segment rule can match, and the visitor receives the Environment default. The same happens if the application asks with an identity but never sends the trait a segment needs. A segment for “country equals Germany” simply cannot match a person whose country was never reported.

SituationWhat Flagsmith can doWho receives the answerDesign advice
No identity sent at allAnswer from the Environment default onlyEvery anonymous visitor alikeMake the default a safe general experience
Identity sent, no traitsApply identity overrides and percentage segmentsUsers who match, otherwise the defaultSend traits that segments depend on
Trait sent in a different formatThe segment may not matchThe person falls to the defaultAgree on one clean format for each trait
Identity created but data not yet loadedOnly the default is availableThe person for a momentDo not show a half loaded personalised page
Everyday analogy

A cinema offers student discounts to anyone who shows a student card. A person who forgets the card is not turned away, they simply pay the standard price. The standard price is the default for anyone whose special status cannot be shown.

!
Common trap

If every “premium only” feature has a default of off, then a bug that stops traits from being sent will silently remove premium features from paying customers. Monitor how many people fall through to the default, so such a bug is noticed by you before a customer notices it.

The moment a visitor signs in

A person often starts as an anonymous visitor and becomes a known user partway through a visit. Before sign-in, they receive the Environment default. After sign-in, segments and overrides may change some answers. If a feature suddenly switches on or off the moment someone logs in, the screen may jump in a way that feels strange. Plan for this by keeping the pre-login experience simple, and by refreshing flags once, calmly, straight after sign-in rather than letting values change in the middle of a task.

11How to Choose a Good Default: Five Questions

There is no universal answer, such as “always off”. There is a short method that works for any flag.

1

What does the old behaviour look like?

For most new features the proven choice is the world as it was before the flag. Start there.

2

Which failure is worse?

Compare the harm of showing the feature wrongly with the harm of hiding it wrongly. Pick the smaller harm.

3

Could the default cost money or trust?

Anything involving payments, personal data or promises to customers needs special care.

4

Does the feature protect the system?

If the flag guards against overload, losing the protection may be worse than losing the feature.

5

Can I live with it for an hour?

If the default stayed in place for sixty minutes, would the business cope? If not, think again.

FlagWorse failureTherefore the default is
New payment sheetCustomers cannot pay with an untested screenOff, using the old proven sheet
Fraud check on large ordersFraud passes while the check is missingOn, because losing the protection is worse
Premium export toolA non-paying customer gets a paid tool by accidentOff, because nobody should gain access by accident
Maintenance bannerA confusing banner appears with no real maintenanceOff, no banner
Heavy recommendation panelPages slow down in a traffic peakDepends on whether protection or experience matters more, decided in advance
Everyday analogy

When a traffic light breaks, drivers treat the junction as a four way stop. Nobody voted on this during the emergency. The rule says: when you cannot trust the signal, slow down and take turns. A good default is a four way stop for your feature.

Write the reasoning in the description

A default is only half a decision without its reason. Put one sentence in each flag’s description, so that the next person understands without asking. Useful descriptions read like this: “Off by default, because the old payment sheet is proven and failing back to it is harmless.” Or: “On by default, because losing this check during an outage would let large fraudulent transfers through.” Descriptions like these also teach new engineers how the team thinks, and they are far more helpful than “controls the new thing”.

12Fail-Safe or Fail-Open? Matching the Default to the Purpose

Two famous phrases from engineering describe opposite leanings. Both are correct, in different situations.

Fail-safe and fail-open

A system that is fail-closed (also called fail-secure) stops or denies when something goes wrong. A bank vault door stays shut if the power fails. A system that is fail-open allows or continues when something goes wrong. A fire exit door swings open if the power fails, because trapping people is worse than letting someone through. Which is right depends entirely on what the danger is.

Lean closed

Protecting access

Premium tools, admin screens and anything revealing private data. If unsure, do not show.

Lean closed

Unfinished features

Release flags for work that is not tested. If unsure, keep the old behaviour.

Lean open

Protecting the system

Rate limits, fraud checks and safety guards. If unsure, keep the protection running.

Lean open

Core journeys

Signing in and paying. If unsure, keep the proven path working so people are not blocked.

Notice that “off” is not always the safe answer. A flag that enables a protection is safest when its default is on. A flag that enables a risky new behaviour is safest when its default is off. The skill is to ask, for each flag, which direction protects people and the business.

Everyday analogy

A hospital’s medicine cupboard locks when the power fails, to keep drugs safe. The same hospital’s emergency exits unlock when the power fails, to let people out. Same building, same power failure, opposite defaults, and both are right.

Scenario: a safety guard on large payments

A payments company has a boolean flag that enables an extra identity check on very large transfers. During a platform incident, Flagsmith is unreachable for several minutes. Because the code default for this flag is “on”, the check keeps running and fraud attempts are blocked. If the default had been “off” by habit, the company would have briefly lost protection at a time when attackers watch for exactly such moments.

When the answer is mixed

Some flags guard behaviour where both directions carry a cost. A recommendation panel may slow the site if it runs during a traffic peak, yet hiding it may cost sales. In such cases, decide in advance what matters most for the situation in which the default will be used, and note it. If the default is used because Flagsmith is unreachable, that is usually a moment of general trouble, and lighter behaviour tends to be wiser. Writing “when in trouble, lighter is better” in the description gives future engineers a rule they can apply to similar flags.

13Defaults by Kind of Flag

Practitioners sort flags into a handful of kinds. Each kind has a natural default, which saves thinking from scratch every time.

The kinds, briefly

Release flags hide unfinished work and are short lived. Experiment flags compare versions with real users. Operational flags let engineers change system behaviour under stress. Kill switches turn a risky feature off in an emergency. Permission flags give certain customers or staff special access. This classification has been popularised by engineers writing on well known software design sites.

KindCreation defaultDefault in codeWhy
Release flagOffOffUnfinished work must stay hidden until released on purpose
Experiment flagOff, with the control as the valueThe control valueThe proven version is the fair comparison and the safe fallback
Operational flagOff, until tuning is neededThe normal, healthy behaviourTuning is for emergencies, not for everyday life
Kill switchOn, meaning the feature runsUsually onThe feature is meant to run, and the switch exists to stop it
Permission flagOffOffNobody should gain a capability by accident
i
Use the table as a start

The table gives you a first guess, not a law. Run the five questions from Chapter 11 when a flag is unusual, such as a kill switch that guards something where “on” is risky, and write the reasoning in the description.

Everyday analogy

A kitchen has different safe settings for different tools. The oven is switched off by default when you leave. The fridge is left on by default when you leave. Nobody has to think about it each time, because each appliance has a natural resting state. Flag kinds have natural resting states too.

14Defaults for Numbers and Text: The Zero Trap and Others

Values look simple, yet they hide the most surprising default bugs. A little discipline in code prevents nearly all of them.

The zero trap

When a number is missing, many programming languages quietly treat it as zero. Zero might be harmless, or it might change meaning completely. A “maximum items in basket” of zero could mean customers cannot buy anything. A “retry limit” of zero could mean never try again. A “timeout” of zero could mean wait forever. The same quiet zero can be a disaster in one place and invisible in another.

Units matter

A value of “five” is meaningless without a unit. Is that five seconds, five minutes or five hundred milliseconds? If one team writes the value thinking in seconds and the code reads it as milliseconds, the feature misbehaves in a way that looks like a mystery. Put the unit in the feature’s name and description, for example “partner_timeout_seconds”, so nobody has to guess.

Defend your code

Treat every value that comes from Flagsmith the same way you would treat input from a stranger. Check that it exists, check that it is the type you expect, and check that it lies within a sensible range. If it fails any check, use the default in code. This habit is sometimes called clamping: forcing a value to stay between a lowest and highest acceptable number.

SettingSensible rangeIf the value is outside the rangeReason
Results per page5 to 50Use 20A typo of 5000 would crash the page
Partner timeout in seconds1 to 30Use 5Zero or very large values cause hangs
Retry attempts0 to 5Use 3Too many retries can flood a struggling partner
Banner message length0 to 140 charactersShow no bannerA pasted essay would wreck the layout
Everyday analogy

A shower has a safety stop on the hot tap, so that however far you turn it, the water never scalds. Even if someone fits the wrong handle, the stop holds. Clamping is the safety stop for numbers that arrive from outside.

!
Danger

Flag values can be edited by humans in a dashboard, and humans make typos. A dashboard value is not a trusted source until your code has checked it.

True and false stored as values

A feature can carry a value that is itself the text “true” or “false”, or a true and false type. This is a different thing from the enabled state of the feature. A feature may be enabled with a value of false, which the code must read as “feature on, setting off”. When values and states disagree, a missing value could be read either way, depending on the language. If you need a yes or no answer, use the enabled state, and keep values for numbers and text. If you must store a boolean value, give the default in code explicitly and name the feature so the meaning is obvious.

15When Exactly Is the Default Used? A Catalogue of Cases

It helps to list every situation in which a default takes over, so none comes as a surprise.

SituationWhich default is usedVisible to the user?How to stay safe
Person matches no overrideEnvironment defaultYes, it is their normal experienceMake the Environment default a good general answer
No identity suppliedEnvironment defaultYesDesign for anonymous visitors
Required trait never sentEnvironment defaultYes, often unnoticedMonitor trait delivery
Flagsmith unreachable at app startDefault in codeUsually yesTest the app with no connection
Flagsmith unreachable laterLast known values, or default in codeOften notKnow how your SDK caches
Flag name does not existDefault in codeQuietlyShare flag names in one place and review changes
Flag deleted, code remainsDefault in codeQuietlyRemove code before deleting the flag
Wrong Environment key usedThe other Environment’s defaultYes, but confusingKeep keys separate and clearly named
Value of the wrong typeDefault in code, if the app checksDependsValidate every value

Notice that some defaults are part of normal life, such as the Environment default for ordinary users, while others are emergency measures, such as the default in code. Both deserve care, but the second kind deserves it before the emergency, because there will be no time to think during one.

Everyday analogy

A house has a spare key under a flowerpot, a neighbour with another, and a locksmith’s number on the fridge. Each is a fallback for a different failure, and none helps unless it was arranged before you were locked out.

16Defaults, Caching and the Last Known Value

Between a fresh answer and a default sits a third possibility that is often better than either: the last answer you remember.

Fresh, remembered, or default

Most SDKs keep a copy of the flags they last received, either in memory or, for mobile and browser apps, in local storage on the device. If a later request fails, a well designed SDK can carry on with the last known values instead of falling all the way back to the default in code. This is usually a better experience, because the last known values were chosen by a person and reflected the real state of the business a moment ago.

flowchart TD
  A["App needs flag value"] --> B{"Can SDK fetch fresh values?"}
  B -- Yes --> C["Use fresh value"]
  B -- No --> D{"Does SDK hold earlier values?"}
  D -- Yes --> E["Use last known value"]
  D -- No --> F["Use default in code"]
    
Fig 4. Three levels of answer: fresh, last known, and the default in code.

Why this matters for the default you choose

The default in code is used only when the first two options fail. That happens most often when an application starts for the very first time with no connection, or when its stored copy has been cleared. Because those moments are rare but serious, the default should still be chosen with care, even if you expect to use it seldom.

MomentFresh values?Last known values?Result
Normal runningYesYesFresh values
Short network blipNoYesLast known values
First ever start, no networkNoNoDefault in code
App data cleared by the userMaybeNoFresh if reachable, otherwise default
Server restarting with no copyNoNoDefault in code until it reconnects
Everyday analogy

If you cannot reach a friend to ask which restaurant to meet at, you first try remembering what you agreed yesterday. Only if you remember nothing do you fall back on the habit of meeting at the usual cafe. Fresh answer, remembered answer, usual habit: the same ladder.

i
Know your SDK

Whether and how an SDK keeps last known values depends on the language, the mode and the options chosen. Read the documentation for the SDK you use, and test it by switching the network off on purpose.

How old is too old?

Last known values are helpful, but they do age. A value remembered from an hour ago is almost always still right. A value remembered from last week might not be, especially if a kill switch has been flipped since. Teams usually set a maximum age for stored values, after which the application prefers its coded default to a stale memory, or tries harder to refresh. The right age depends on how quickly your flags change and how much harm a stale value could do. For flags that guard safety, shorter is wiser.

17Defaults When You Create or Clone an Environment

Environments are born with defaults too, and the way they are created affects everything that follows.

A new Environment starts somewhere

When you add an Environment to a Project, it needs a state for every existing feature. Depending on how it is created, that state may come from a basic blank starting point, or from a copy of another Environment. Flagsmith lets you create a new Environment by cloning an existing one, which copies its states and values. This is the quickest way to start a new Staging or regional Environment from a known good set of values.

1

Decide the source

Choose which Environment is the best model for the new one. Often it is Staging, not Production, so no live exceptions are copied.

2

Create by cloning

The new Environment receives the same feature states and values as the source at that moment.

3

Review the copied defaults

Read through the list. Some values, such as partner addresses or limits, may need to differ in the new stage.

4

Give it its own keys

Every Environment has its own Environment keys. Use the new keys only in the applications for that stage.

Drift: the slow divergence

Once separate, Environments drift. Someone changes a value in Production during an incident and forgets to match Staging. Weeks later a test passes in Staging and fails in Production, because their defaults are no longer alike. Regular side by side comparison, especially before launches, catches drift early.

Everyday analogy

A chain opens a new branch by copying the layout and procedures of a well run existing branch. Over the years each branch makes small local changes. Unless head office occasionally compares them, no one can say which differences were deliberate and which were accidents.

!
Clone with care

Cloning Production copies its live settings, including special overrides for real customers. Make sure you understand what is being copied before putting those rules into a test stage that other people can freely change.

Regional Environments and local defaults

Some products add an Environment for a particular region, for example one for a country with different laws or payment methods. Its defaults are likely to differ from the global Production Environment, and that is fine, provided the differences are deliberate and written down. A short table listing which values differ between a regional Environment and Production, and why, saves the next engineer from “fixing” a difference that was important.

18The Silent Default: Typos, Deleted Flags and Mismatched Names

The most irritating bugs around defaults are the ones where nothing visibly goes wrong. The default simply keeps being used.

How silent defaults happen

A flag lookup is made by name. If the name in code does not exactly match the name in Flagsmith, the lookup finds nothing, and the default quietly takes over. This can happen through a simple typo, a difference in capital letters, an extra space, a rename in the dashboard, or a deletion. The code does not crash, because defaults are designed to avoid crashes. The feature just never turns on, and engineers lose hours wondering why a flag that is clearly enabled has no effect.

CauseWhat Flagsmith showsWhat the app doesCure
Typo in the flag name in codeFlag enabledUses default, feature never appearsKeep names in one shared list in the code
Different capital lettersFlag enabledUses defaultAgree one style and enforce it
Flag renamed in the dashboardFlag under a new nameOld name no longer foundNever rename, create a new flag instead
Flag deleted too earlyNo such flagUses defaultRemove code first, then delete the flag
Test build using the wrong Environment keyFlag enabled in another EnvironmentReads that Environment’s stateName keys clearly and keep them separate

Making silent defaults loud

The best protection is to turn silence into a signal. When the application asks for a flag that exists in its shared list but receives the default because the flag was not found, write a log message or increase a counter. A graph of “defaults used” that suddenly rises tells you that names or connections are broken long before customers complain.

Everyday analogy

If you post a letter to a wrong address, no alarm sounds. It simply never arrives, and you only find out when someone asks why they heard nothing. A tracking number turns that silence into information. A counter of “defaults used” is the tracking number for flags.

19Rollout Patterns Shaped by the Default

The same audience can be reached in two opposite ways, depending on which side the default is placed. Each has a natural use.

Pattern A: default off, exceptions on

The Environment default is off, and chosen groups are switched on through segment overrides. This is the classic rollout. The feature starts invisible, staff see it first, a pilot group next, a percentage after that, and finally the default itself is switched on. It is the safest pattern for new features, because anything not mentioned is unaffected.

Pattern B: default on, exceptions off

The Environment default is on, and chosen groups are switched off. This suits a feature that is already live for everyone, where you need to hold it back from a few people, for example customers in a country where a law forbids it, or a partner with an older integration that cannot cope. It also suits the “kill for one group” case: leave the feature on for most, and quickly switch it off for the one segment where a problem appears.

flowchart LR
  subgraph PA["Pattern A: default off"]
    A1["Environment default: Off"] --> A2["Staff segment: On"]
    A1 --> A3["Ten percent segment: On"]
    A1 --> A4["Everyone else: Off"]
  end
  subgraph PB["Pattern B: default on"]
    B1["Environment default: On"] --> B2["Restricted country segment: Off"]
    B1 --> B3["Legacy partner segment: Off"]
    B1 --> B4["Everyone else: On"]
  end
    
Fig 5. The same flag, arranged with the default on either side.
QuestionPattern A: default offPattern B: default on
Best forReleasing a new featureExcluding a few groups from a live feature
Unknown people receiveThe feature is hiddenThe feature is shown
Risk if a trait is missingPeople miss out on the featurePeople who should be excluded may see it
Danger to watchForgetting to widen the audienceA missing exclusion rule exposing the feature wrongly
Everyday analogy

A club can have a guest list, where only named people enter, or a banned list, where everyone enters except named people. A guest list is safer for a private party. A banned list suits a public venue. The choice depends on what happens to an unknown person at the door.

!
Mind the missing trait

Pattern B depends on exclusion rules matching correctly. If a person’s country trait never arrives, they fall to the default, which is on, even if they should have been excluded. When legal or contractual exclusions are involved, prefer a design where missing information leads to the safe outcome.

Moving from Pattern A to Pattern B

Many features travel through both patterns in their lifetime. They begin as Pattern A, with the default off and groups added. When the feature reaches everyone, the default is switched on, and the remaining overrides are removed. Later, if a particular group must be excluded, a segment override for that group is turned off, which is Pattern B. At each hand-over, check that no old override is left behind pointing the wrong way. A stray “on” override for staff is harmless once the default is on, but a stray “off” override can quietly hide the feature from a group for months.

20Defaults and Percentage Rollouts

A percentage rollout gives different answers to different people at the same time. The default plays a quiet but important role.

How the default and the percentage work together

A percentage segment selects a share of identities, such as ten percent of all users. A segment override then gives those people a different answer from the default. Everyone outside the percentage receives the Environment default. So at “ten percent”, ninety percent of users are, in effect, served by the default. This is why the default must be a good experience in its own right, because it is the experience of the large majority during most of a rollout.

Steady groups

The split is steady for each identity. Flagsmith works out a position for each person from their identity, so the same person stays in the same group as the percentage widens. Someone in the first ten percent remains included at twenty-five percent. No person flickers between two experiences. This steadiness only works for people with an identity. An anonymous visitor with no identity cannot be placed in a percentage and therefore always receives the default.

1%

Canary

A tiny audience proves the feature does not crash. Ninety-nine percent receive the default.

10%

Early slice

Enough users to notice patterns. The default still serves nine in ten people.

50%

Half and half

The new path carries serious load. The default is now half of all experience.

100%

Switch the default

The final step is to set the Environment default to the new behaviour and retire the segment.

Everyday analogy

A new bus route is first run on one morning in ten, while the old route serves the rest. For most of the trial, the old route is what most people experience, so it must stay reliable. Only when the new route proves itself does the old one retire.

21Managing Defaults at Scale: The Register

With ten flags, you can remember every default. With a thousand, you need a system.

Keep names and defaults in one place in code

Instead of scattering flag names and their default values across many files, collect them in one shared section of the code. Each entry states the flag name and the default for it. A developer who needs a flag finds it there, and a reviewer sees any change to a default at a glance. This also protects against typos, because a name is written once.

Keep a human register too

In your team’s documents, keep a short table listing each important flag, its kind, its default in code, the reason for that default and its owner.

FlagKindDefault in codeReasonOwner
checkout_new_payment_sheetReleaseOffOld sheet is provenStore team
search_results_per_pageValue20Long-standing normalSearch team
payments_enable_large_transfer_checkProtectionOnLosing the check is worsePayments team
reports_enable_advanced_exportPermissionOffNo accidental accessReports team

Review defaults when code changes

Whenever a pull request adds a flag or changes a default, make it a standing question in the review: what happens if the answer never arrives? A reviewer who asks this one question prevents a surprising number of incidents.

✓
A simple rule

No flag enters the codebase without a written default and a one line reason. If the author cannot explain the default in a sentence, the default has not been chosen yet.

A checklist for code review

  • Is the flag name taken from the shared catalogue, not typed by hand?
  • Is there an explicit default, and does it lean towards the smaller harm?
  • Is the reason for the default written in the flag’s description?
  • If the flag carries a number or text, is the value checked for type and range?
  • Is there a test with the flag on, off, and with no answer?
  • Does the default agree with the Environment default, or is the difference explained?

22Testing Your Defaults

A default that has never been exercised is a guess. Testing turns it into a promise.

The unreachable test

The most valuable test is also the simplest: run the application, in a test setting, with Flagsmith deliberately unreachable. Start it with no connection, with a wrong key, or with the network blocked, and watch what happens. Every important screen should still work, using its defaults. If something breaks, you have found a missing or careless default while the stakes are small.

The three states of every flag

For each flag, test three situations. With the flag on, the new behaviour works. With the flag off, the old behaviour works. With no answer at all, the default works. Most teams remember the first two and forget the third, which is exactly the situation the default exists for.

TestHow to set it upWhat to check
Flag onEnable in Staging for the test userNew behaviour appears and works end to end
Flag offDisable in StagingOld behaviour appears and nothing is broken
No answer, first startRun the app with the network blocked and no stored copyDefault behaviour appears, no errors on screen
No answer, laterBlock the network after a successful startLast known values are used, app stays calm
Missing flagAsk for a name that does not exist in the test EnvironmentDefault behaviour appears, and a warning is logged
Bad valueTemporarily set a nonsense value in StagingThe app rejects it and uses the default
Everyday analogy

A building holds fire drills, not because anyone expects a fire, but because an untested exit plan is only a hope. Switching off the network in a test is your fire drill.

✓
Make it fast

Provide a small helper in your test code that lets a test choose a flag’s state, or choose “no answer”, without calling Flagsmith at all. Fast tests that do not depend on the network are tests people actually run.

23Who May Change a Default? Permissions and Change Control

Changing an Environment default in Production is among the most powerful actions in Flagsmith, because it affects everyone not covered by a special rule.

Why it needs care

An override changes the experience of a chosen group. The Environment default changes the experience of everybody else, which is usually most of your users. Flipping it in Production is therefore the equivalent of a release to the whole population, and should be treated with the same seriousness as deploying code.

Layers of permission

Flagsmith controls access at the Organisation, Project and Environment levels. Creating features, and thereby setting the creation default, is a Project-level permission. Changing an Environment’s feature state, which sets the Environment default, is an Environment-level permission. Give the first more widely, and the second only to a small, trained group for Production. Where your plan offers change requests, require a second person’s approval before a Production default changes, so that one slip cannot affect every customer.

ActionLevelTypical groupCare needed
Create a feature with a creation defaultProjectProduct engineersModerate, because it can spread to Environments
Change a default in DevelopmentEnvironmentProduct engineersLow
Change a default in StagingEnvironmentEngineers and testersModerate
Change a default in ProductionEnvironmentRelease groupHigh, ideally with approval and a note in chat
Change the default in codeCode repositoryDevelopers through reviewHigh, as it needs a release and rarely changes
Everyday analogy

Changing the house special on a restaurant’s printed menu needs the owner. Changing tonight’s special on the blackboard can be done by the head chef. The more people a change affects and the longer it lasts, the higher the decision goes.

!
Check current options

Exact permission names, approval flows and scheduled changes depend on your version and plan. Treat the principles as stable, and confirm specifics in your dashboard before writing a policy.

24Security Thinking About Defaults

Defaults are decisions about what happens by accident. That makes them a security topic.

Permissive defaults are a risk

A default that grants access, for example enabling a premium tool when no information is available, is a standing invitation for mistakes to become leaks. The principle of fail-safe defaults says the opposite: when in doubt, deny, unless denial itself is dangerous. For flags that gate capabilities, choose defaults that give nothing away.

Defaults are visible to clients

Anything sent to a browser or phone can, in principle, be read by the user. That includes flag names and values. Do not put secrets, internal code names or private comments in values or descriptions that clients can read. Where your version offers the option, hide disabled flags from client applications, so people cannot discover the names of unannounced features.

A flag is not a lock

A flag decides what the interface shows. It does not protect the data behind it. Anything that really must be protected needs a permission check on your own servers, whatever the flag or its default says. A default of “off” that hides a button does not stop a determined person from calling the underlying service directly.

Public

Client-side key

Belongs to one Environment, is safe in websites and apps, and can only read flag values.

Secret

Server-side key

Belongs to one Environment and must stay on your servers. It unlocks richer access, such as local evaluation.

Master

Organisation key

Lives above the Project and manages Flagsmith itself. Never place it in an application.

Everyday analogy

A “staff only” sign on a door guides honest visitors. It does not stop a thief. For that you need a real lock and a key. A default and a flag are the sign, and your server checks are the lock.

Do not store personal data in values

Because values travel to client applications, never place personal data, private email addresses or customer lists inside a flag value or a trait you do not need. A value should be a small setting, not a record. If you must target by a personal fact, send a minimal derived trait, such as a plan name or a region, rather than the raw data, and follow your company’s rules on privacy.

25Monitoring: Seeing When Defaults Are Being Used

The cure for a silent default is to make it speak.

What to measure

Three simple measures give real insight. The default usage count is how often the application fell back to a default in code, per flag. The missing flag count is how often it asked for a flag that does not exist. The fetch failure count is how often it failed to reach Flagsmith at all. In a healthy system all three are close to zero, and any sudden rise deserves a look.

Defaults used
how often code fell back, per flag
Missing flags
asks for names that do not exist
Fetch failures
times Flagsmith could not be reached

Putting it on a graph

Send these counts to the monitoring tool your team already uses, such as Datadog, and place flag changes on the same graph by using the integration that announces them. When defaults-used jumps up right after a deployment, you know a name was mistyped. When fetch failures jump at the same time as a platform incident, you know the app is running on last-known values. The audit log of Flagsmith records who changed what and when, which completes the story.

1

An application is released

A new version asks for a flag by a name that has a typo.

2

The counter rises

The “missing flag” count for that name jumps from zero.

3

An alert tells the team

A simple threshold on the counter sends a message to the team channel.

4

The fix is small

The name is corrected in the next release, and the counter falls back to zero.

Everyday analogy

A car’s dashboard has a light that comes on when the engine is running on a backup setting. You can still drive, but you know something needs attention. A counter of defaults used is that dashboard light for your flags.

26Anti-patterns and Common Mistakes

These traps appear in almost every company that adopts feature flags. Learn them now and avoid paying for them later.

ANTI-PATTERN 01Avoid
The mistake

Leaving the default in code to the SDK’s built-in answer.

Why it hurts

The SDK has no idea what is safe for your product. Its built-in answer may suit a release flag and be dangerous for a protection flag.

Do this instead

Write an explicit default for every flag, with a one line reason, and keep them together in one place in the code.

ANTI-PATTERN 02Avoid
The mistake

Creating new flags enabled by default, with the creation default spreading to Production.

Why it hurts

An unfinished feature reaches real customers the instant it is created, before anyone has chosen to release it.

Do this instead

Create release flags disabled, and use the Project safety setting that prevents flag defaults from spreading, where your version offers it.

ANTI-PATTERN 03Avoid
The mistake

Treating “off” as automatically safe.

Why it hurts

For a flag that enables a protection, off is the dangerous direction. A fraud check or rate limit silently disappears when the default is off.

Do this instead

Ask for each flag which failure is worse, and set the default towards the smaller harm.

ANTI-PATTERN 04Avoid
The mistake

Trusting a value from the dashboard without checks.

Why it hurts

A typo such as a zero or an extra digit changes behaviour dramatically, and a human edit is far easier than a code release.

Do this instead

Validate type and range, and use the default in code when a value fails the check.

ANTI-PATTERN 05Avoid
The mistake

Defaults in code that disagree with the Environment default and nobody knows why.

Why it hurts

A person flips a flag in the dashboard and expects one behaviour, but during a failure the application behaves differently, causing confusion in the middle of an incident.

Do this instead

Where they must differ, write the reason in the flag’s description, so the next engineer sees the gap and understands it.

More small mistakes worth naming

  • Never testing the application with Flagsmith unreachable.
  • Using zero as a quiet default for numbers that mean limits or times.
  • Letting Staging and Production defaults drift apart.
  • Reusing a flag name for a new purpose, so old code reads a default that no longer fits.
  • Not counting how often defaults are used.
ANTI-PATTERN 06Avoid
The mistake

Using the Environment default as a permanent holding place for temporary experiments.

Why it hurts

Months later nobody knows whether the current default is the winner of an experiment or a leftover from a test. A baseline that nobody can explain is a risk for every future change.

Do this instead

At the end of every experiment, make the winner the plain default, remove the variations, and write a line in the description saying so.

27Failure Scenarios and Recovery

Things will go wrong. Teams that planned their defaults recover in minutes, and teams that did not recover in hours.

Scenario one: Flagsmith is unreachable during a launch

Applications serve last known values where they have them, and defaults in code where they do not. If defaults were chosen well, customers see the old, proven behaviour and the launch simply pauses. Once the platform returns, the flags apply as planned. After the incident, review how many users fell to defaults and whether any default was wrong.

Scenario two: a feature never turned on, though the flag is enabled

Check three things in order. Is the application using the correct Environment key? Does the flag name in the code match exactly the name in Flagsmith? Has the app refreshed its values since the change? Most “it does not work” reports end at one of these. The counter of missing flags makes the second check instant.

Scenario three: a Production default was changed by mistake

Restore the previous value first, which the audit log shows. Customers come before investigation. Afterwards ask how a person with permission came to flip the wrong Environment, and consider approvals and clearer Environment names.

Scenario four: a numeric value was mistyped

A value of two thousand where twenty was meant should have been rejected by the range check in code. If it was not, correct it in the dashboard at once, then add the missing range check so the next typo is harmless.

Scenario five: premium features vanished for paying customers

1

Notice the rise in defaults used

The monitor shows many premium flags falling to their default of off.

2

Look at traits

A release changed how the plan trait is sent, so segments no longer match.

3

Restore the trait

Roll back or fix the sending code, so identities carry the right plan again.

4

Confirm and tell customers

Check a sample of paying accounts and communicate if anyone was affected.

Scenario six: a flag was deleted while code still used it

The application falls back to its default, which is why defaults matter. Recreate the flag with the same name, restore its states from the history, and plan a proper removal from code before deleting it again.

Scenario: a cautionary tale from finance

One of the best known software disasters involved the trading firm Knight Capital in 2012. In widely reported accounts, a release reused an old switch that woke long-dead code on a server that had not been updated, and the firm lost roughly four hundred million dollars in about forty-five minutes. Details have been debated, but the lessons for anyone who relies on defaults are clear: never reuse the meaning of an old flag name, make sure every server runs the same version, and remember that an old default can wake up in unexpected ways.

RUNBOOK NOTEKeep handy
Write these down

Where the defaults register lives, how to find a flag’s previous value, which dashboard shows defaults used, who may change Production, and who to tell. If any answer is “I would have to search for it”, write it down today.

After any incident: three questions for the review

Once the pressure is off, hold a short, blame-free review. Ask three questions about defaults. Which defaults were actually used, and for how long? Did each one behave as the register said it would? And is there any flag where the default surprised us? Write the answers on one page, update the register, and fix any default that proved wrong. Over a year, a team that does this builds a register that is accurate because every incident has sharpened it.

28Scaling, Speed and Resilience

Defaults are also what let a flag system serve millions of users without becoming a weak link.

Do not wait forever for an answer

Any network call can be slow. If an application waits for Flagsmith before showing a page, a slow answer becomes a slow page. Good applications set a short timeout, which is a limit on how long to wait, and use the default if the answer has not arrived. A timeout of a few hundred milliseconds for a page-critical flag is common, while background refreshes can wait longer.

Start fast on a cold start

A cold start is when an application launches with nothing remembered. Mobile apps opened for the first time, and servers freshly started, are cold. During a cold start there are no last known values, so the default in code is what the first screen uses. Many teams make the first screen independent of flags where possible, and let flags refine later screens, so the cold start is quick and calm.

Cache and local evaluation

Fetching flags on every check would be slow and costly. SDKs keep flags in memory and refresh on a timer. Some server SDKs offer local evaluation, downloading the complete rule set once and deciding flags inside your own server in microseconds. In this mode the platform is not asked for each decision, so even a long outage affects only how fresh the rules are, not whether decisions can be made.

flowchart LR
  U["Millions of users"] --> APPS["Your application servers"]
  APPS --> SDK["SDK with local cache"]
  SDK -- "periodic refresh" --> PROXY["Optional local proxy"]
  PROXY -- "occasional sync" --> FS["Flagsmith platform"]
  SDK -. "if nothing available" .-> DEF["Default in code"]
    
Fig 6. Layers of answer: fresh from the platform, cached locally, and finally the default in code.
Everyday analogy

A city does not ask the central water plant every time someone turns a tap. Water waits in local towers, and houses are supplied even if the plant has a short problem. Caches are the towers, and the default in code is the emergency reserve tank at the bottom of each house.

Choosing timeouts for different kinds of flag

Kind of flagHow long to waitWhat to do on timeout
A flag that shapes the first screenVery short, a few hundred millisecondsShow the default screen at once
A flag for a later, optional panelA little longer, around a secondHide the panel, or show it in default form
A background refreshSeveral secondsKeep last known values and try again later
A protection flag on a critical pathShort, then lean to the protective defaultKeep the protection running

29Worked Example: Designing Defaults for an Online Store

Ideas become clear when applied. Follow the team at a fictional retailer, Northwind, as they decide every default for four flags.

The situation

Northwind sells goods through a website and a mobile app. A team of about twenty people works on both. They are preparing four flags for the coming sale season: a new payment sheet, a limit on search results, a large transfer safety check, and an advanced export tool for business customers. For each, they walk through the same questions from Chapter 11.

FlagKindCreation defaultProduction Environment defaultDefault in codeReason
checkout_new_payment_sheetReleaseOffOff, then segments, then onOffThe old sheet is proven. Failing back to it is harmless
search_results_per_pageValue2020, lowered to 12 on sale days20, with a range of 5 to 50Twenty is the long-standing normal. Out-of-range values are ignored
payments_enable_large_transfer_checkProtectionOnOnOnLosing the check is the worse failure
reports_enable_advanced_exportPermissionOffOff, with premium segment onOffNobody should gain a paid tool by accident

The steps they followed

1

Switch on the safety setting

The Project setting that stops creation defaults spreading is enabled, so new flags never appear in Production by accident.

2

Write the register

The four flags and their defaults go into one table in the team’s documents, with owners.

3

Put defaults in code

The same four defaults are written in one shared section of the code, with a one line reason each.

4

Add range checks

The search value is accepted only between five and fifty, otherwise twenty is used.

5

Test with no connection

In Staging, the team starts the app with the network blocked and confirms every screen still works.

6

Add the monitor

A graph of “defaults used” is added to the dashboard the team already watches, with an alert on a sharp rise.

7

Rehearse a failure

During a quiet hour, the team blocks Flagsmith from a test server and watches the counters rise and the product stay calm.

The result on sale day

During the sale, a short network problem prevents some mobile apps from refreshing flags. The apps use last known values. A few brand new installs with no stored copy use the coded defaults: the old payment sheet, twenty results, the safety check on and the export tool off. Customers shop normally. The “defaults used” graph rises for twenty minutes, then falls. Engineers read the graph, confirm that all defaults behaved as designed, and write a short note. Nobody is woken at night.

Everyday analogy

A shop that has planned for a power cut has torches by the till, a manual card machine in a drawer and a sign saying “cash only for a while”. Customers hardly notice, and the staff stay calm. The coded defaults are the torches and the sign.

30Auditing the Defaults You Already Have

Few teams start from nothing. If flags already exist, a short audit can find the weak defaults before an incident does.

1

List every flag in use

Search the code for flag lookups, and compare with the features in the Project. Note flags that exist in only one place.

2

Record each default in code

For each flag, write down what happens if no answer arrives. Where the code has no explicit default, mark it in red.

3

Ask the five questions

For each flag, ask which failure is worse and whether the recorded default leans the right way.

4

Compare with Environment defaults

Check whether the default in code differs from the Production default, and whether the difference is deliberate.

5

Fix the worst first

Start with flags guarding money, personal data and protections. Cosmetic flags can wait.

6

Add tests and monitors

For each fixed flag, add the unreachable test and the defaults-used counter.

What you findHow seriousWhat to do
No explicit default for a protection flagHighSet the default to on today and test it
A release flag whose default is onHighCheck whether unfinished work is exposed, and change the default to off
A number with no range checkMediumAdd a sensible range and a default
Default in code differs from Production with no explanationMediumWrite the reason in the description or align them
A flag that no code uses any moreLow, but it adds clutterRemove it after confirming nothing reads it
Everyday analogy

A homeowner who walks around checking that every smoke alarm has a battery is doing an audit. It takes an hour, nothing is on fire, and it is the most valuable hour of the year. Auditing defaults is the same quiet insurance.

✓
Success signal

You know the audit worked when anyone on the team can state the default of any important flag in one sentence, and give the reason for it.

Quick wins in one afternoon

If time is short, three small actions give most of the benefit. First, switch on the Project setting that stops creation defaults spreading, if your version offers it. Second, find every flag that guards money, personal data or a protection, and give each an explicit default in code. Third, add a single counter for defaults used to your monitoring tool. These three steps take hours, not weeks, and they catch the failures that hurt most.

31Advantages, Disadvantages and Trade-offs

Having several layers of default is a design choice with real benefits and real costs.

Advantages

  • Releases and incidents stay calm, because every question has a planned answer.
  • New features can be created safely, with no effect on customers until released.
  • Layered answers let you choose the right fallback for each situation.
  • Experiments have a safe control to retreat to.
  • Applications remain usable when the flag platform is slow or unreachable.
  • Defaults can be reviewed and tested like any other part of the design.

Disadvantages and trade-offs

  • Four places hold a default, so confusion about which one applies is common.
  • Defaults in code can only change with a release, so mistakes there are slow to correct.
  • Defaults can hide problems, because the product keeps working while quietly using a fallback.
  • Environment defaults drift apart unless someone compares them.
  • A wrong default may stay unnoticed for a long time, because it only matters in rare moments.
  • Defaults need documentation and discipline, which cost team time.

The central trade-off: conservative or helpful

A very conservative default, such as “hide every new thing”, is safe but may keep customers from benefits. A very helpful default, such as “show everything available”, is generous but exposes unfinished or risky behaviour. There is no single right point. The method in this guide is to choose per flag, according to which failure hurts more, and to write the reasoning down.

When defaults are not the right tool

A default is a fallback, not a business rule. If something must be true by law or contract, such as showing a required notice to customers in a certain country, relying on a flag default is fragile. Such rules belong in code or in a controlled data store with proper review. Flags and their defaults are best for behaviour that changes often and can safely fall back.

A word on teams and habits

The technical side of defaults is small. The habit side is large. A team that asks “what is the default?” in every design review and every code review will rarely be surprised. A team that never asks will be surprised repeatedly, and each surprise will feel like bad luck rather than a missing question. If you adopt only one habit from this guide, make it the single question: if the answer never arrives, what do we want to happen?

32Best Practices Checklist

A short list to keep nearby. If you do these ten things, you will avoid most of the pain described in this guide.

01

Say which default you mean

Creation, Environment, control value or code. Name it in every discussion.

02

Create flags disabled

Creation should never be the same event as release. Use the Project safety setting where available.

03

Write every default in code

Never leave the answer to the SDK’s built-in choice. Give each default a reason.

04

Ask which failure is worse

Lean towards the smaller harm. For protections, that often means on.

05

Validate values

Check type and range, and fall back to the default when a value is nonsense.

06

Keep a register

One table with flag, default, reason and owner. Update it when flags change.

07

Test the unreachable case

Run the app with no connection before every major release.

08

Make defaults visible

Count defaults used and missing flags, and alert on sudden rises.

09

Protect Production defaults

A small named group, approvals where available and a note in chat.

10

Remove old flags

Delete code first, then the flag, so no stale default is left to wake up.

Making the checklist stick

Lists on their own fade from memory. Turn the ten points into a short template that is attached to every new flag’s ticket, so each point is answered while the flag is being created rather than remembered later. Review the template twice a year, and drop any item that never changes an outcome. A checklist of six living questions beats a checklist of twenty that people tick without reading.

33Glossary: Every Term in One Place

Keep this table nearby while reading documentation or talking with your team.

TermPlain meaning
DefaultThe answer used when nothing more specific applies.
Creation defaultThe starting state and value entered when a feature is first created.
Environment defaultThe baseline state and value of a feature inside one Environment.
Control valueThe original value of a split feature, served to users outside every variation.
Default in codeThe fallback used by the application when no answer arrives.
Safe defaultA default chosen because it causes the least harm if used.
Fail-safe defaultThe principle that unspecified cases should lean towards the safe outcome.
Fail-openContinuing to allow or run when something goes wrong.
Fail-closedStopping or denying when something goes wrong.
Feature flagA switch inside software that decides whether a behaviour is active.
ValueInformation such as a number or text attached to a feature.
Remote configurationChanging a value in a running application without a new release.
Multivariate featureA feature with several values split between users by percentage.
VariationOne of the alternative values in a split feature.
ProjectThe home of one product’s features, segments and tags.
EnvironmentOne stage, such as Development or Production, holding live states.
Feature stateWhether a feature is on, and its value, in one Environment.
IdentityAn end user or account whose flags are being worked out.
TraitA fact attached to an identity, such as plan or country.
SegmentA rule that selects a group of identities.
Segment overrideA different answer for a segment in one Environment.
Identity overrideA different answer for one specific identity.
SDKA ready made library that lets your application talk to Flagsmith.
Default flag handlerSDK logic that decides what to return when a flag is missing or unreachable.
Last known valueThe most recent answer an SDK received, kept for use when fetching fails.
Local evaluationDownloading rules once and deciding flags inside your own server.
Cold startLaunching an application with nothing remembered.
ClampingForcing a value to stay inside a sensible range.
DriftEnvironments gradually becoming different from each other.
Audit logA diary of who changed what and when.

34Frequently Asked Questions

Quick answers to the questions that come up most often.

Q1What is the default value of a feature in Flagsmith?
It depends on which default you mean. At creation it is the starting state and value you enter. Inside an Environment it is the baseline state and value used for anyone matching no override. In your application it is the fallback written in code. Always say which one you mean.
Q2Does the value I set when creating a feature go to every Environment?
By default it can, because the feature is shared across the Project and every Environment needs a starting state. Many versions offer a Project setting that prevents flag defaults from spreading, so check yours and use it for safety.
Q3Who receives the Environment default?
Everyone who matches no identity override and no segment override, including visitors with no identity and people whose needed traits were never sent.
Q4What happens if my app cannot reach Flagsmith?
Most SDKs use the last known values if they hold any, and otherwise a built-in answer or your own default flag handler. Behaviour varies between SDKs, so read the one you use and test with the network off.
Q5Should the default in code match the Environment default?
Often yes, because it keeps behaviour predictable. They may differ on purpose, for example when the Production default is on for a new feature that you still want to fall back to off. If they differ, write the reason in the feature’s description.
Q6Is “off” always the safe default?
No. For flags that enable a protection, such as a fraud check, off removes the protection and is the dangerous direction. Ask which failure is worse for each flag.
Q7What is the default of a split feature?
The control value. It is served to people who are not placed in any variation, including the share of users left unassigned by the variation percentages.
Q8Why does my flag do nothing even though it is enabled?
Common causes are a wrong Environment key, a mismatch between the name in code and the name in Flagsmith, or an app that has not refreshed. In each case the default in code quietly takes over, so check the missing flag counter.
Q9How do I stop a bad number in the dashboard from breaking my app?
Validate every value in code. Check that it exists, that it has the right type and that it lies in a sensible range, and use the default in code when it does not.
Q10Do anonymous visitors get the default?
Yes. With no identity, no segment can match, so the visitor receives the Environment default. Design that default as a good general experience.
Q11Can changing a default in Production be risky?
Very. It changes the experience of everyone not covered by a special rule, usually most users. Limit the right to a small group, announce changes, and use approvals where your plan allows.
Q12How do I know my defaults are being used?
Count them. Send a counter of defaults used and missing flags to your monitoring tool, place flag changes on the same graph, and alert on sharp rises.

35Summary and Key Takeaways

Remember these seven ideas

  • There are four defaults, not one. The creation default, the Environment default, the control value and the default in code each live in a different place and act at a different moment.
  • The Environment default reaches most people. Overrides help chosen groups, but everyone else receives the baseline, so it deserves the strongest protection in Production.
  • Create flags disabled. Creation should never be the same event as release, and the Project safety setting helps stop creation defaults spreading to every Environment.
  • Choose by the worse failure, not by habit. Off is right for risky new behaviour and wrong for protections, so ask what harm each direction could cause.
  • Always write the default in code. Never leave it to the SDK, validate values from the dashboard and keep a register of defaults with reasons.
  • Test and watch the fallback. Run the app with no connection, and count defaults used so silent fallbacks become visible.
  • A default is a fallback, not a lock. Enforce real permissions on your servers, and keep legal or contractual rules out of flag defaults.