What Is a Feature Flag?
A beginner-friendly, production-minded guide to the simple switch that lets teams ship code safely, release features gradually, and undo mistakes in seconds, without redeploying anything.
Imagine you are renovating the kitchen in your home. The workers install a brand-new stove, but they do not connect the gas yet. The stove sits there, fully built, fully installed, and completely harmless. On the day you feel ready, you turn one valve and the stove comes alive. If you smell something odd, you turn the valve back and everything is safe again. Nobody has to tear the stove out of the wall.
A feature flag works in exactly the same way, but for software. Engineers build and install a new feature inside the running application, but they keep it switched off. Later, someone flips a switch, and the feature turns on for a few people, then more people, then everyone. If something goes wrong, the switch flips back, and the problem disappears in seconds. This one idea has quietly changed how companies such as Facebook, Netflix, Amazon, Google, and GitHub deliver software to millions of people every day.
In this guide you will learn what a feature flag is, why it exists, how it works on the inside, which types exist, how big companies use them, and which mistakes to avoid. We assume you know nothing about the topic. Every new word is explained the first time it appears, and every big idea comes with an everyday comparison so it sticks in your memory.
1What a Feature Flag Actually Is
Start with the plainest possible definition, then build up from there.
A feature flag (also called a feature toggle, feature switch, or feature gate) is a decision point in your software that is controlled by a setting you can change while the software is running. In the code, there is a question: “Should this user see the new behavior or the old behavior?” The answer does not come from the code itself. It comes from a setting stored somewhere outside the code. Change the setting, and the answer changes, with no new build, no new deployment, and no restart.
That is the whole idea. Everything else in this guide, such as percentage rollouts, targeting rules, experiments, and kill switches, is simply a more powerful way to decide what the answer to that one question should be.
The simplest possible example
Suppose an online shop wants to redesign its checkout page. The old checkout page works fine and earns the company money every minute. The new checkout page looks nicer, but nobody knows yet whether it has hidden bugs or whether customers will like it. Without a flag, the team has two bad choices: replace the old page for everyone and hope for the best, or keep the new page hidden on a separate branch of code for weeks while it slowly drifts away from the rest of the project.
With a flag, the team keeps both pages in the application. A flag named “new checkout page” decides which one a customer sees. At first the flag is off for everybody, so nothing changes. Then the flag is turned on for the company’s own employees. Then for one percent of customers. Then ten percent, then half, then everyone. At every step the team watches error rates and sales. If anything looks wrong, they flip the flag off and customers instantly return to the trusted old page.
Think of a dimmer switch for a lamp, not a plain on/off switch. A basic feature flag is like a normal switch: on or off. A rollout flag is like a dimmer: you raise the brightness slowly, one notch at a time, and you stop or turn it down the moment the room feels wrong. The lamp (your feature) was already screwed into the ceiling long before you touched the dimmer.
Where feature flags live
Feature flags live in two places at once. The decision point lives inside your application code, usually as a very small “if this flag is on, do this, otherwise do that” check. The setting itself lives in a separate place, which might be a configuration file, a database table, or, in most serious companies, a dedicated flag management service with a friendly web dashboard. Because the setting is separate from the code, a product manager or on-call engineer can change it without touching the code at all.
Do not confuse a feature flag with a normal configuration setting such as a database address. A configuration setting describes how the system connects to things. A feature flag describes which behavior a particular user should experience, and it usually changes often and is meant to disappear someday.
Why this matters so much
Releasing software has always been stressful because of one painful fact: you never truly know how new code behaves until real people with real data use it in the real world. Testing catches many problems, but not all of them. Feature flags accept this reality and give teams a safe way to learn from real traffic while limiting the damage if something is wrong. They turn the scary, all-or-nothing moment of “launch day” into a calm, gradual, reversible process.
2Deploy Versus Release: The Idea Behind Everything
Feature flags work because they separate two words that most people accidentally use as if they meant the same thing.
To understand why flags are valuable, you must first understand the difference between deploying and releasing. In many teams these words are used loosely, but they describe two different events, and flags exist to pull them apart.
Deploying means putting new code onto the servers that run your application. It is a technical event. Engineers do it, pipelines automate it, and customers usually cannot tell it happened. Releasing means making a feature available to users. It is a business event. Product managers, marketing teams, and customers care about it. Before feature flags, these two events happened at the same moment: the instant new code arrived on the servers, every user saw it. If the code had a bug, every user met the bug.
A theater crew builds a new set behind a closed curtain during the afternoon. That is deployment: the set exists and sits on stage. The audience sees it only when the curtain rises in the evening. That is release. The crew can test the lights, practice the moves, and fix loose boards while the curtain is down, and they decide exactly when the curtain rises. A feature flag is the curtain rope.
| Question | Deployment | Release |
|---|---|---|
| What happens? | New code is copied to production servers | Users are allowed to experience the new behavior |
| Who decides? | Engineering and delivery pipelines | Product, business, and engineering together |
| How risky is it? | Low, if the new code is switched off | Depends on how many users see it at once |
| How often can it happen? | Many times per day | Whenever the business is ready |
| How is it undone? | Roll back or redeploy old code, which is slow | Flip the flag, which takes seconds |
Why teams deploy so often
Modern companies deploy extremely often. Amazon engineers reported in 2011 that the company was pushing a deployment roughly every dozen seconds on average. Flickr talked publicly in 2009 about deploying more than ten times per day, which was shocking at the time. Frequent deployment is a good thing because small changes are easier to understand, easier to test, and easier to fix than huge changes bundled together over months.
But frequent deployment creates a problem. If every deployment immediately changed what users see, the product would feel chaotic, and half-finished work would leak into the live site. Feature flags solve this. Engineers can deploy unfinished code all day long, hidden behind flags that are off, and the product only changes when someone deliberately flips a switch.
The branching nightmare flags remove
Without flags, teams often hide unfinished work by keeping it on a separate branch, which is a private copy of the code. A feature might live on its own branch for six weeks. Meanwhile, the main code keeps changing, and the two copies drift apart. When the day comes to merge them, the team faces a painful pile of conflicts. This is jokingly called “merge hell.”
Feature flags let teams practice trunk-based development, which means everyone adds small changes to the same main line of code every day. Half-finished features are included, but safely wrapped in a switch that is off. Conflicts stay tiny, because nobody drifts away for long.
A flag that is off is not magic armor. The new code still ships to production and still sits inside your application. A careless change can break things even when the flag is off, for example by altering a shared function or slowing down start-up. Flags control behavior, not the mere presence of code.
3A Short History of Feature Flags
The idea is older than the name. It grew from a simple “if statement” into a whole industry.
Programmers have used switches in code for as long as programs have existed. Early software used command-line options, environment variables, and configuration files to turn behaviors on and off. Those switches were usually set once, when the program started, and changing them meant restarting the program. They were tools for system administrators, not for product teams.
The modern feature flag grew up when websites began shipping changes continuously. Large web companies discovered that their biggest risks were not the code they wrote but the moment when that code met millions of real users. They needed a way to control exposure, and they built it themselves.
Early days: switches in config files
Teams used static settings read at start-up. Useful, but changing them required a restart, and only engineers could do it.
2009: Flickr shares its approach
Flickr described deploying many times a day and hiding unfinished work behind flags, which helped popularize the habit of launching features “dark” before anyone saw them.
Late 2000s: Facebook builds Gatekeeper
Facebook created an internal system called Gatekeeper that decided which users saw which features, letting the company test new work on employees and small groups before the whole world.
2010: Continuous Delivery book
Jez Humble and David Farley’s book made frequent, automated releases a mainstream goal, which increased demand for ways to hide unfinished features safely.
2014 onward: commercial platforms appear
Companies such as LaunchDarkly and others turned flags into managed services with dashboards, targeting rules, and audit trails, so teams no longer had to build everything from scratch.
2017: Martin Fowler’s site publishes a taxonomy
An article by Pete Hodgson on Martin Fowler’s website organized flags into clear categories, and that vocabulary became the industry standard.
2022 onward: open standards
OpenFeature, a vendor-neutral standard hosted by the Cloud Native Computing Foundation, appeared so that applications could talk to any flag provider through one common interface.
The trend is clear. Flags began as private tricks inside a few large companies, became a shared engineering practice, and are now a standard part of the toolbox, with agreed vocabulary and common standards.
4Core Concepts and Vocabulary
Eight words explain almost every conversation about feature flags.
Before going deeper, let us build a small dictionary. Each term below appears again and again in tools, documentation, and job interviews.
Flag Key
The unique name of a flag, such as “new-checkout-page”. Code asks for the flag by this name.
Variation
One possible answer a flag can give. A simple flag has two (on and off). Others can have many, such as three button colors.
Context
Facts about who is asking: user ID, country, plan type, device, app version. Rules use these facts to decide.
Targeting Rule
An “if this, then that” instruction, such as “if the country is Canada, serve the new version.”
Rollout Percentage
The share of users who get the new variation, for example 5 percent, chosen in a stable and repeatable way.
Segment
A saved group of users, like “internal employees” or “beta testers,” that many flags can reuse.
Environment
Separate copies of flag settings for development, testing, and production, so experiments never leak into the live site.
Default Value
The fallback answer used when the flag system cannot be reached or the flag is missing. It should always be the safe choice.
Flag key and variation
The flag key is simply the flag’s name. Think of it as a label on a switch panel in a building’s electrical room: “Third floor lights,” “Parking gate,” “Lobby fountain.” Code uses the key to ask, “What is the state of this switch?” The answer is called a variation. A boolean flag has two variations, true and false. A multivariate flag can have more, such as “blue,” “green,” and “orange,” or even numbers like a timeout of 5, 10, or 30 seconds.
Context and targeting rules
The context is the information about the person or request being evaluated. Imagine a nightclub doorman. He does not flip a coin for every guest. He looks at facts: Is this person on the guest list? Are they old enough? Is the club full? Those facts are the context, and the doorman’s instructions are the targeting rules. A rule might say, “Employees always get in; people from the beta list get in; everyone else gets in only if the club is below capacity.” Flag systems work the same way, except that the doorman evaluates thousands of guests per second.
Rollout percentage and segments
A percentage rollout gives the new variation to only a slice of users. A very important detail is that the slice must be stable. If a customer sees the new page on Monday, they should still see it on Tuesday. If the slice reshuffled on every request, a user might see the new page, then the old page, then the new page again in a single minute, which would be confusing. Flag systems solve this with a repeatable calculation, explained in the next chapters. A segment is a reusable named group of users. Instead of pasting a list of employee IDs into twenty flags, you define the segment “employees” once and reference it everywhere.
Environment and default value
An environment is a separate world with its own flag settings. A flag can be on in the testing environment and off in production at the same time. This is like a flight simulator: pilots can try anything without risking a real aircraft. The default value is the fallback answer a flag gives if something fails, such as the flag service being unreachable. Choosing the default wisely is one of the most important decisions in flag design, and we return to it in the reliability chapter.
“What is the difference between a flag key, a variation, and a rule?” A strong answer: the key names the flag, the variations are the possible outputs, and rules are the logic that picks which variation a given context receives.
5The Four Types of Feature Flags
Not all flags are the same. Knowing the type tells you how long the flag should live and who should control it.
Engineers often group flags into four families. This grouping matters because each family behaves differently. Some flags should exist for a few days. Others may stay for years. Some are changed by engineers, others by product managers or support staff. Mixing them up is a common source of confusion and technical mess.
| Type | Purpose | Typical Lifespan | Who Changes It |
|---|---|---|---|
| Release flag | Hide unfinished or risky features and roll them out gradually | Days to weeks | Engineers and product managers |
| Experiment flag | Compare versions to learn which performs better | Weeks, until a winner is clear | Product and data teams |
| Operational flag | Control system behavior, such as disabling a heavy feature under load | Weeks to years | On-call engineers and operations |
| Permission flag | Give certain customers access to paid or special features | Months to years | Product, sales, and support |
Release flags
A release flag (sometimes called a release toggle) is the most common type. Its job is to let unfinished or risky work travel to production safely. The flag begins off, the feature is built behind it, and eventually the flag is turned on for everyone. At that point the flag has done its job and should be deleted. Release flags are meant to be short-lived. They are like scaffolding around a building under construction: essential during the work, an eyesore if left behind afterward.
For example, when a streaming service builds a new “continue watching” row, engineers can ship the code in pieces over two weeks, all hidden behind one release flag. Nothing looks different to customers until the whole row is ready.
Experiment flags
An experiment flag splits users into groups so the company can measure which version works better. This is the technique behind A/B testing. Group A sees the old design, group B sees the new design, and the team compares what each group does, such as how many people click “buy.” Netflix is widely known for relying heavily on this kind of testing, even for small details such as which artwork appears for a title. An experiment flag needs extra care: users must stay in the same group for the whole experiment, and the assignment must be recorded so analysts can count results correctly.
Operational flags
An operational flag, often called an ops toggle, controls how the system behaves under stress. The best-known example is the kill switch: a flag that instantly disables a feature that is causing trouble. Picture the emergency stop button on a factory machine. You hope never to press it, but you are very glad it exists. For instance, a travel website may have a flag that turns off the “personalized recommendations” panel during a huge sales event, because that panel is expensive to compute and not essential. Ops flags are often long-lived because the safety they provide is permanent.
Permission flags
A permission flag decides whether a particular user or customer has access to a feature, based on who they are. A software company might offer an “advanced analytics” dashboard only to customers on its premium plan. A flag can express that rule. These flags are the longest-lived because they are part of the product’s business model, and they overlap with traditional entitlement or subscription systems.
Think of a hospital. The scaffolding on a new wing is a release flag: temporary. A laboratory comparing two medicines is an experiment flag: it ends when the result is known. The emergency shut-off valve for the oxygen supply is an operations flag: it stays forever. The badge that opens the pharmacy door only for pharmacists is a permission flag: it reflects who you are, not what is being built.
Label every flag with its type when you create it. A simple naming habit, such as starting names with “release,” “exp,” “ops,” or “perm,” tells future engineers whether a flag is safe to delete.
6Architecture and Components of a Flag System
A flag looks tiny in code, but a production flag platform is a small distributed system of its own.
A single “if” statement is easy. Making that statement answer correctly, instantly, and safely for millions of users in many countries is harder. That is why serious flag platforms have several moving parts, each with a clear job. The diagram below shows a typical layout, from the person who changes a flag to the user who feels the effect.
flowchart LR A["Engineer or Product Manager"] --> B["Flag Management Console"] B --> C["Flag Store Database"] B --> K["Audit Log"] C --> D["Flag Delivery Service"] D --> E["CDN and Edge Cache"] E --> F["Server SDK inside Backend Service"] E --> G["Client SDK inside Mobile or Web App"] U["End User"] --> LB["Load Balancer"] LB --> GW["API Gateway"] GW --> F F --> H["Application Decision: old or new behavior"] G --> H F --> I["Event Pipeline"] I --> J["Metrics and Experiment Dashboard"]
The management console
The management console is the website where people create flags, write rules, and flip switches. It is the control panel of the whole system. Good consoles require logins, check permissions, and ask for confirmation before changing sensitive flags in production. Everything that humans do goes through here.
The flag store
The flag store is the database that holds every flag’s definition: its key, variations, rules, rollout percentages, and environment settings. It is the single source of truth. When you flip a switch in the console, this store is updated first. Because every service depends on this data, it is usually replicated across several machines or regions so that one failure cannot lose it.
The audit log
The audit log records who changed what, and when. If a flag change causes an outage at 2 a.m., the first question is, “What changed right before the problem?” The audit log answers instantly. Many companies also require such a record for compliance reasons, which means proof for regulators that changes were controlled and approved.
Delivery service, CDN, and edge cache
The flag delivery service packages the current rules and sends them to the applications that need them. To make this fast and cheap, it usually sits behind a CDN (content delivery network), which is a worldwide network of servers that keep copies of data close to users. A CDN copy of the rules means an application in Tokyo does not need to ask a data center in Virginia every time. This is like a chain of bookstores keeping popular books on local shelves instead of shipping each copy from a central warehouse on demand.
The SDK
The SDK (software development kit) is a small library installed inside your application. It is the piece your code talks to. When your code asks “Is the new checkout on for user 1001?”, the SDK answers. It downloads the rules, keeps them in memory, receives updates, and evaluates them. There are two flavors, and understanding them is important.
Server-side SDK
- Runs on your own backend servers
- Downloads the full ruleset and evaluates locally
- Rules stay private and secure
- Answers in a tiny fraction of a millisecond
Client-side SDK
- Runs in browsers and mobile apps
- Usually receives only the finished answers for one user
- Must never receive secret rules, because users can inspect their own devices
- Needs extra care with slow or offline connections
Event pipeline and analytics
Every time a flag is evaluated, the SDK can record a small event: which flag, which variation, which user group. These events travel through an event pipeline, a conveyor belt for data, into dashboards. This is how a team can say, “Users who saw the new checkout completed 3 percent more purchases.” Without this data, an experiment would just be a guess.
Push or pull: how SDKs stay up to date
SDKs learn about changes in one of two ways. With polling, the SDK asks every so often, such as every 30 seconds, “Has anything changed?” It is like checking your mailbox on a schedule. With streaming, the SDK keeps a connection open, and the service pushes changes the moment they happen, like a doorbell. Streaming gives faster kill switches, usually within a second or two. Polling is simpler and cheaper at huge scale. Many platforms offer both.
“Where should flag evaluation happen, on the server or on the client?” A thoughtful answer: evaluate on the server whenever possible because rules stay private and decisions are consistent. Evaluate on the client only for presentation choices, and send down just the finished results, never the rule logic.
7How a Flag Is Evaluated Internally
What actually happens in the fraction of a second between your code asking a question and getting an answer?
Evaluation is the act of turning a flag’s rules plus a user’s context into a single answer. It happens inside the SDK, in memory, without any network call in the common case. That is why a well-built flag check is extremely fast. The SDK already holds a copy of every rule, so it only has to run a short sequence of checks.
flowchart TD
A["Request arrives with user context"] --> B{"Is the flag switched off globally?"}
B -- "Yes" --> Z["Serve the off variation"]
B -- "No" --> C{"Is the user on an individual allow list or block list?"}
C -- "Yes" --> D["Serve the value set for that user"]
C -- "No" --> E{"Does a targeting rule match this user?"}
E -- "Yes" --> F["Serve the variation from that rule"]
E -- "No" --> G{"Is the user inside the rollout bucket range?"}
G -- "Yes" --> H["Serve the new variation"]
G -- "No" --> I["Serve the fallthrough variation"]
Step 1: the master switch
Most systems first check whether the flag is enabled at all. If someone has turned the flag off, evaluation stops immediately and the off variation is served. This is the kill switch behavior, and putting it first guarantees that an emergency off really means off, regardless of what other rules say.
Step 2: individual overrides
Next, the system checks for special cases about specific users. An engineer might add themselves to an allow list so they can try the feature in production first. Support staff may add a customer to a block list because the feature misbehaves for that account. Individual overrides are checked early because they represent deliberate, human choices.
Step 3: targeting rules
Then the rules run in order, top to bottom, like a list of instructions given to a doorman. The first rule that matches wins. For example: “If the user’s email ends with the company domain, serve the new version. Else if the country is Germany, serve the old version. Else continue.” The order of rules matters a great deal, so good consoles make it obvious and let you reorder them carefully.
Step 4: percentage rollout with hashing
If no earlier rule decided the answer, the system uses the rollout percentage. The challenge is to pick, say, 10 percent of users in a way that is fair, even, and stable. Flipping a coin per request would fail the stability test. Instead, the system uses a hash function, a mathematical recipe that turns any piece of text into a number, always the same number for the same text.
Here is how it works in everyday terms. Take the flag key and the user’s ID and combine them into one piece of text, such as “new-checkout-page” plus “user-1001”. Feed it to the hash function, which produces a big number. Divide by 100 and keep the remainder, which gives a bucket between 0 and 99. If the rollout is 10 percent, users whose bucket is 0 through 9 get the new version. Because the recipe is deterministic, user 1001 always lands in the same bucket for that flag, so their experience is stable day after day.
Imagine a school sorting students into 100 lockers by a fixed rule based on their name and the subject. Student Maria always gets locker 37 for science, every single day, without anybody remembering it. If the school says, “Lockers 0 through 9 try the new science lab,” Maria is not included. If the school later widens it to “0 through 49,” Maria is included, and no one who was already inside gets kicked out.
Why the flag key is part of the hash
Mixing the flag key into the hash is a clever detail. If the bucket depended only on the user ID, the same unlucky 5 percent of users would be chosen for every experiment, and they would become guinea pigs for everything. By including the flag key, each flag shuffles users differently, so the burden is spread fairly across the whole user base.
Growing a rollout without disruption
Because buckets are fixed, raising a rollout from 10 percent to 25 percent only adds users. Nobody who already has the feature loses it. This is exactly what you want during a gradual launch. If the rollout were reshuffled, thousands of users would see the feature appear and vanish, producing confusing bug reports and spoiling any measurements.
Step 5: the fallthrough
Finally, if nothing else applied, the user gets the fallthrough (or default rule) variation. In a rollout, that is typically the old, safe behavior.
If your app has 10 million users and the rollout is 1 percent, about 100,000 people will see the new feature. That is a big enough group to reveal real problems, yet small enough that a bug affects only a sliver of your audience. Choosing the first percentage is about balancing learning speed against risk.
8Data Flow and the Life of a Flag
Follow the data from start-up to update, and follow the flag from birth to deletion.
How data flows when an application starts
When an application server boots up, its SDK needs the rules before it can answer anything. The sequence below shows how that happens and how later changes arrive.
sequenceDiagram participant App as Application Server participant SDK as Flag SDK participant CDN as Delivery Network participant Store as Flag Store App->>SDK: Start up with environment key SDK->>CDN: Request full ruleset CDN->>Store: Fetch if not cached Store-->>CDN: Ruleset version 42 CDN-->>SDK: Ruleset version 42 SDK->>SDK: Keep rules in memory App->>SDK: Is new checkout on for user 1001 SDK-->>App: Yes Store-->>CDN: Update to version 43 CDN-->>SDK: Stream update version 43 SDK->>SDK: Swap in new rules
Notice that after start-up, the application never has to wait on the network to answer a flag question. The question goes to the SDK, the SDK looks at its in-memory rules, and the answer returns almost instantly. Meanwhile, updates arrive quietly in the background, and the SDK swaps in the new rules atomically, which means all at once, so there is no moment when half of the old rules and half of the new rules are active.
The lifecycle of a release flag
Every healthy flag has a life with a beginning, a middle, and an end. The final step is the one most teams forget, and forgetting it causes much of the pain people associate with flags.
flowchart LR A["Create flag"] --> B["Build feature behind flag, off"] B --> C["Deploy to production, still off"] C --> D["Test with internal users"] D --> E["Gradual rollout"] E --> F["Fully released to everyone"] F --> G["Remove flag and old code path"]
Create and name the flag
Choose a clear name, record the owner, the type, and the planned removal date. A flag without an owner is a flag that will be forgotten.
Build behind the flag
Engineers write the new behavior and wrap it in a flag check. The flag is off everywhere, so the live product does not change.
Deploy while dark
The code reaches production with the flag off. This is called a dark launch: the code is live but invisible. Teams can also run the new path in the background without showing results, to compare it against the old one.
Test with insiders
Turn the flag on for employees. Real production data and real infrastructure reveal problems that test servers never could.
Roll out gradually
Raise exposure in steps, pausing to watch errors, speed, and business numbers. Stop or reverse at the first sign of trouble.
Release to everyone
When the flag has been fully on and stable for a reasonable time, the feature is considered released.
Clean up
Delete the flag check, delete the old code path, and archive the flag. This keeps the code simple and prevents hidden complexity from piling up.
Each leftover flag doubles the number of code paths in the area it guards. Ten forgotten flags can create over a thousand possible combinations, and nobody can test them all. Cleaning up is not optional housekeeping. It is part of the feature’s definition of done.
9Rollout Strategies: Choosing Who Sees What, and When
The flag is the tool. The rollout strategy is how you use it wisely.
Knowing how to flip a switch is easy. Knowing when and for whom to flip it is the real skill. Over the years teams have developed several standard strategies, and most real launches combine more than one.
Dark Launch
Ship the code with the flag off, or run it silently in the background. Nobody sees it, but engineers learn how it behaves.
Internal Dogfooding
Turn the feature on for your own employees first. If it breaks, only colleagues are affected, and they can report it quickly.
Canary Release
Expose a tiny slice, such as 1 percent, and watch closely. Named after canaries once carried into coal mines to detect danger early.
Ring Deployment
Expand in widening circles: team, then company, then beta customers, then everyone. Microsoft has described this approach for large products.
Beta Opt-In
Let interested customers raise their hands. They tend to be forgiving and give richer feedback.
Geographic Rollout
Release one country or region first, often a smaller market, before the largest ones.
Canary releases in more detail
A canary release is the workhorse of safe launching. You begin with a very small percentage, and you define in advance what “healthy” means: error rate below a certain level, response time within a certain limit, purchases not dropping. You wait long enough to see enough traffic. If all is healthy, you raise the percentage to 5, then 25, then 50, then 100. If any number goes wrong, you stop or turn the flag off. The key is deciding the success measures before you start, so you do not talk yourself into ignoring warning signs.
Kill switches
A kill switch is a flag whose only purpose is to shut something down quickly. The best teams put kill switches around anything risky: a new payment provider, a heavy search feature, an integration with an outside company, or an expensive background job. During an incident, the on-call engineer does not need to understand the whole system. They simply open the dashboard and flip the switch. That is the difference between a two-minute problem and a two-hour outage.
A/B tests and experiments
In an experiment, the goal is not safety but learning. You divide users into groups, give each group a different variation, and compare outcomes. Doing this properly requires patience and honesty. You need enough users for the result to be trustworthy, a clear question decided in advance, and the discipline not to stop the test the moment the numbers look good, because early numbers wobble randomly. Large companies like Google and Netflix are widely known to run enormous numbers of experiments, and many product decisions that look obvious turn out wrong when measured.
Combining strategies
A realistic launch might look like this: deploy dark on Monday, turn on for employees Tuesday, canary at 1 percent Wednesday, 10 percent Thursday, 50 percent the next Tuesday, and 100 percent after a week of stable numbers. The kill switch remains available the whole time. Each step is a decision, and each decision can be reversed.
Production example: a gradual launch at scale
When a large social platform adds a new feed layout, it cannot risk showing a broken page to hundreds of millions of people. It dogfoods with employees, releases to a small percentage in a few countries, checks that servers cope with the extra load, and only then widens exposure. Facebook’s Gatekeeper system was built precisely for this kind of controlled, staged exposure.
10Advantages, Disadvantages, and Trade-offs
Feature flags are powerful, but they are not free. A good engineer sees both sides.
Advantages
- Separates deployment from release, which lowers stress and risk
- Instant rollback by flipping a switch instead of redeploying
- Gradual exposure limits the damage of bugs
- Testing in production with real traffic and real data
- Enables A/B testing and data-driven decisions
- Supports trunk-based development and fewer painful merges
- Lets non-engineers control launch timing
- Allows targeted access for beta groups, regions, or paying plans
Disadvantages
- More code paths, so more complexity and more to test
- Stale flags pile up and become technical debt
- Flag systems become a critical dependency that must itself be reliable
- Misconfiguration risk: one wrong click in production can hurt many users
- Harder debugging, since behavior depends on hidden settings
- Possible inconsistency between services if they see different flag states
- Extra cost if you buy a platform or build and maintain one
- Privacy concerns if user attributes are sent to third parties
The central trade-off: speed versus complexity
Every flag buys you safety and flexibility today, and charges you a small amount of complexity tomorrow. One flag costs almost nothing. A hundred forgotten flags cost a fortune, because every developer must reason about which combinations are possible. The art of using flags well is to enjoy the benefits while paying the lowest possible complexity bill, mainly by removing flags quickly once their job is done.
Testing becomes a multiplication problem
If a feature has two states, you must make sure both work. If two flags interact, you now have four combinations. Three flags give eight combinations. In practice you cannot test every combination, so you focus on the combinations that real users will encounter: everything off, the target state fully on, and the transitions between them. Keeping flags independent from one another is the best way to keep this multiplication under control.
Consistency across services
In a large system made of many small services, a single user action may pass through several of them. If the first service believes the flag is on and the second believes it is off, the user may get a broken experience. Imagine a shop whose web page shows a new discount price while the billing service still charges the old price. Good designs pass the flag decision along with the request or make sure that all services evaluate the same rules using the same user identity, and they accept that updates may take a second or two to spread everywhere.
The most famous cautionary tale is Knight Capital in August 2012. A trading firm reused an old flag that, on one of its eight servers, still pointed to long-forgotten code. In roughly 45 minutes the firm lost around 440 million dollars. The lessons were deployment discipline, deleting dead code, and never recycling an old flag name for a new purpose.
11Security and Privacy
A switch that controls what millions of people experience deserves the same protection as any other powerful control panel.
Who is allowed to flip which switch?
Not everyone should be able to change every flag in production. A good platform offers role-based access control, which means permissions are tied to jobs. A junior engineer may freely change flags in the testing environment but need an approval for production. A support agent may be able to toggle one customer-facing flag. A payment-related kill switch might require two people to approve changes. Think of the keys in a bank: the cashier, the manager, and the vault officer carry different keys.
Approvals and audit trails
For sensitive flags, many companies require a review step, similar to a code review, before a change reaches production. Every change is logged with the person, the time, the old value, and the new value. This is not just bureaucracy. It protects against honest mistakes, helps in investigating incidents, and satisfies auditors who must verify that changes to critical systems are controlled.
Do not hide security behind a flag
A flag decides what a user experiences, not what a user is allowed to do. If a feature exposes private data, the real protection must be in the backend’s permission checks. A hidden button is not a locked door. Someone with a browser’s developer tools could still call the hidden feature directly if the server does not verify their rights. Always enforce authorization on the server, and treat the flag as a convenience on top of it.
Client-side exposure
Remember that anything delivered to a browser or phone can be read by the person holding it. If a client-side SDK downloads the full ruleset, a curious user can read rules such as “the secret pricing experiment applies to these segments.” Teams avoid this by sending clients only the final answers for the current user, and by never placing secrets, internal names, or sensitive logic in flag names or descriptions.
Privacy of user attributes
Targeting often requires information such as an email, country, or plan type. Sending this to an outside flag provider raises privacy and legal questions, especially under regulations such as GDPR. A common solution is to evaluate flags locally inside your own servers, so the user attributes never leave your infrastructure, and to send only anonymous or hashed identifiers to analytics tools. Always give your privacy team a chance to review what is sent.
Protecting the flag system itself
The SDK keys that applications use to connect should be kept secret and rotated when staff leave or keys leak. Separate keys for each environment prevent a test machine from accidentally reading or changing production flags. Treat these keys exactly like database passwords.
“Can a feature flag be used as an authorization mechanism?” A careful answer: no. Flags are for controlling exposure and rollout. Authorization must be enforced by dedicated server-side checks, although permission-style flags may complement a proper entitlement system.
12Monitoring, Logging, and Metrics
Turning a flag on without watching the results is like pressing the accelerator with your eyes closed.
A feature flag is only safe if you can see what happens after you flip it. Good teams plan their observation before launching, deciding which numbers will tell them whether the new feature is healthy. These numbers come in three families.
Technical health metrics
These describe how well the software is running. The key ones are the error rate (how many requests fail), latency (how long requests take, especially the slowest 1 percent, often called p99), throughput (requests handled per second), and resource usage such as processor and memory. When a rollout moves from 5 percent to 25 percent and the error rate climbs, you have found a problem before it hurt everyone.
Business metrics
These describe whether customers behave in healthy ways: sign-ups completed, purchases made, videos watched, support tickets opened. A feature might have no technical errors yet still harm the business, for example by confusing buyers so fewer finish checkout. Technical and business metrics must be watched together.
Flag-specific metrics
The flag system itself should report how often each flag is evaluated, which variations are served, how fresh each SDK’s rules are, and whether any SDK has lost its connection. A sudden drop in evaluations may mean a service silently stopped checking the flag. A stale SDK may be serving old decisions. Dashboards for these numbers are the instrument panel of your flag platform.
Tagging telemetry with the flag state
One of the most useful practices is adding the flag variation to your logs, metrics, and traces. Then, when a user reports a bug, an engineer can quickly filter to “only requests where the new checkout was on” and compare against “requests where it was off.” This turns a mysterious problem into a clear comparison. Without this tagging, debugging flag-related issues becomes guesswork.
Automated guardrails
Advanced setups connect monitoring directly to rollouts. If the error rate of the new variation exceeds a limit, the platform automatically pauses the rollout or even switches the flag off. This is sometimes called a guarded release or automated rollback. It behaves like the safety system on a train that brakes by itself if the driver does not respond.
Write down a one-line “rollback condition” in each flag’s description, such as “turn off if checkout errors exceed 1 percent for five minutes.” During a stressful incident, a pre-agreed rule saves precious minutes and avoids debates.
13Performance, Scalability, and Reliability
What happens when millions of requests per minute all ask the same flag question, and the flag service has a bad day?
Why flag checks are fast
A well-designed flag check does not travel across the network. The SDK holds the rules in memory, and evaluation is a handful of comparisons and one hash calculation. That typically takes a tiny fraction of a millisecond. Even a busy service that checks twenty flags per request barely notices the cost. This is the single most important performance fact: evaluate locally, update in the background.
A restaurant waiter keeps the daily specials memorized instead of walking to the kitchen to ask for each guest. When the chef changes the specials, a runner whispers the update to every waiter once. Answers stay instant, and the kitchen is never flooded with a thousand questions.
Scaling to millions of requests
The number of end-user requests does not directly translate into load on the flag service, because the SDKs answer locally. What the flag service actually serves is rule downloads and update notifications, a number that grows with the count of application instances, not the count of users. A company with 5,000 servers and 50 million daily users sends data to 5,000 SDKs, not 50 million. Putting a CDN in front of the delivery service lets one rule update be copied cheaply to every region. Mobile and browser clients are the harder case, since there may be millions of them, so platforms use edge caching and send small per-user payloads.
The flag service will fail someday
Every network service eventually fails, so designers assume the flag service will be unreachable at some point and plan for it. Several layers of defense exist, and a good system uses all of them.
In-Memory Cache
The SDK keeps the last known rules in memory. If the connection drops, it keeps answering with the last good rules.
Local Persisted Copy
Some SDKs save rules to disk, so a freshly restarted server can start even when the service is down.
Safe Default Values
If no rules exist at all, the code’s built-in default is used. This must always be the safe, well-tested behavior.
Relay or Proxy
Large companies run their own relay inside their network that fetches rules once and shares them with internal services.
Choosing the default value
The default value is a tiny decision with huge consequences. For a risky new feature, the safe default is usually off. But for a protective flag, such as one that enables fraud checks, the safe default may be on. Ask yourself one question: “If the flag system disappears, what behavior would I want?” Write that down as the default, and test it by actually simulating a flag outage.
Stability during updates
Updates should be atomic and ordered. Each ruleset has a version number. SDKs only move forward, never backward, so a late message from an old update cannot overwrite a newer one. They also apply changes as a complete set, as shown earlier. This avoids rare but nasty bugs where a service briefly runs with a mixture of old and new rules.
Avoiding flag-induced slowdowns
Be careful about checking flags inside very tight loops that run millions of times, or about attaching huge user context objects to every check. Evaluate once per request when possible and reuse the answer. Also avoid rules that need slow outside lookups. A rule that calls a database to decide a flag turns a microsecond decision into a slow and fragile one.
“How would you design a flag system that serves ten million requests per minute and survives the failure of its own control plane?” Key points: local in-memory evaluation, CDN-distributed rules, streaming plus polling fallback, versioned atomic updates, persisted last-known-good copies, and carefully chosen safe defaults.
14Design Patterns and Anti-patterns
Good habits keep flags helpful. Bad habits turn them into a tangled mess.
Helpful patterns
Pattern: Keep the decision at the edge
Check the flag once, at a single well-chosen place, such as where a request first enters a service. Then pass the result inward. This avoids scattering the same flag check across dozens of files, which makes the eventual cleanup painful.
Pattern: Use a wrapper or interface
Instead of letting every part of the code call the flag SDK directly, create one small layer that owns all flag questions. If you later switch vendors or adopt the OpenFeature standard, you change one place, not hundreds.
Pattern: Strategy-style branching
When a flag chooses between two behaviors, place each behavior in its own clearly named component and let the flag decide which component to use. This keeps the old and new logic separate and makes deleting the old one easy later.
Pattern: Parallel run for risky rewrites
When replacing a critical system, such as a pricing engine, let both old and new versions run on the same input. Users still receive the old answer, but the system compares the two and logs differences. Once the new version matches for long enough, switch over. GitHub has described using this style of careful comparison when rewriting important parts of its platform.
Pattern: Expiry dates
Give each release flag an expected removal date and an owner. Some teams even make the build fail or send a reminder when a flag outlives its date, so cleanup becomes automatic rather than optional.
Anti-patterns to avoid
The Zombie Flag
A flag that finished its job years ago but still sits in the code. Nobody remembers what it does, and nobody dares delete it. Over time these zombies multiply, slow down understanding, and cause surprises. The cure is ownership, expiry dates, and a regular cleanup habit.
The Nested Flag Maze
Flags inside flags inside flags, where behavior depends on a combination of five switches. Nobody can predict what a user will see, and testing becomes impossible. Keep flags independent, and when one truly depends on another, document it loudly and remove it fast.
Reusing Old Flag Names
Recycling an old flag key for a new purpose is dangerous because some stale service or cached copy may still interpret it the old way. This is the exact trap behind the Knight Capital disaster. Always create a fresh name, and retire old names permanently.
The Giant Configuration Dump
Using the flag system as a general-purpose settings database, storing huge blobs of business data in flags. Flags should carry small decisions. Large or frequently changing business data belongs in a proper database or configuration service.
Flags as a Substitute for Testing
Believing that because you can switch a feature off, you may skip careful testing. Flags reduce the cost of failure, but real users still suffer during the minutes before someone notices. Keep your automated tests, and use flags as an additional layer of protection, not a replacement.
15Best Practices and Common Mistakes
A short checklist that separates calm teams from stressed ones.
Best practices
Name flags clearly
Use descriptive names that say what the flag does and which team owns it. Avoid vague names like “test1” or “newThing.”
Record owner, type, and expiry
Every flag should say who owns it, what type it is, and when it should disappear.
Default to safe
Choose default values that protect users and the business if the flag service fails, and rehearse that failure.
Keep flags small and independent
Each flag should control one clear decision. Avoid chains of flags that depend on each other.
Test both sides
Automated tests should cover the flag on and the flag off, so neither path rots while waiting.
Roll out in small steps and watch
Increase exposure gradually, with pre-agreed health measures and a pre-agreed rollback condition.
Clean up promptly
Schedule flag removal as part of the work. Treat an unremoved release flag as unfinished work.
Protect production changes
Use roles, approvals, and audit logs for important flags.
Common mistakes
Leaving flags forever. The most frequent mistake by far. Teams celebrate the launch and move on, and the flag stays for years.
Turning a flag to 100 percent instantly. This defeats the purpose of having a gradual rollout. Even a “safe-looking” feature deserves at least a small first step.
Forgetting the other services. A flag may be changed in the web service, but a background worker or mobile app still uses old assumptions. Check every place that reads the flag.
Changing flags without telling anyone. A silent change in production confuses people who are debugging at the same time. Announce important changes in the team chat, even when audit logs exist.
Ignoring the off path. Because the new path is exciting, teams forget that the old path must keep working until the flag is removed. A bug in the old path might surface only when someone flips a kill switch during an emergency, which is the worst possible time.
Putting sensitive information in names or descriptions. Flag names can leak into client code. Keep them professional and non-secret.
16Testing Software That Uses Feature Flags
Flags add choices, and every choice must be checked. Here is how teams keep testing manageable.
Testing is where beginners first feel the cost of feature flags. A plain feature has one behavior to verify. A flagged feature has at least two: the version where the flag is off and the version where the flag is on. Because the flag can be changed at any time, both versions must always work. If the old path quietly breaks while everyone is excited about the new one, the first person to discover it will be an on-call engineer who flips a kill switch during an emergency and finds that the fallback is also broken.
Unit tests: check both sides
A unit test checks one small piece of code in isolation. For flagged code, write at least one test with the flag off and one with the flag on. To make this easy, your tests should be able to set a flag’s value directly, without contacting any real flag service. Most SDKs offer a “test mode” or a simple in-memory provider for this reason. It is like a flight simulator for the switch: you decide the cockpit’s state and check that the plane reacts correctly.
Integration tests: check the seams
An integration test checks that several pieces work together, such as a web service, a database, and a payment provider. For flags, the important question is whether the whole journey works in each state. Does the complete checkout, from cart to confirmation email, succeed with the new page enabled? Does it still succeed with the old page? Teams usually run these journeys twice, once per state, in an automated pipeline before every deployment.
Testing the transitions
Many bugs hide not in the “on” state or the “off” state but in the moment of change. Imagine a customer who starts checkout while the flag is off and finishes it after the flag turns on. Does their cart survive? Does the half-filled form disappear? Good tests include a few of these in-between moments, especially for features that store data, because data written by the new version must still be readable by the old version if you ever roll back.
Think of switching a train from one track to another. It is not enough to check that trains run on track A and that trains run on track B. You must also check the junction itself, where the train is halfway between the two and the wheels must turn the right way at the right moment.
The combination problem
If a screen is controlled by three independent flags, there are eight possible combinations, and ten flags would give 1,024. Nobody can test all of those, and fortunately nobody has to. Teams reduce the effort in three ways. First, they keep flags independent so they rarely interact. Second, they test the combinations that real users will actually meet, namely everything off, the planned final state, and a few likely mixtures. Third, they remove old flags quickly so the number of combinations never explodes in the first place.
Testing in production
One of the most valuable uses of flags is testing in the real production environment. Test servers never perfectly copy production, because they lack real data volume, real traffic patterns, and real third-party behavior. With a flag, engineers can turn the feature on only for themselves, use it normally in production, and look for problems. This is safe because ordinary customers still see the old behavior. It is the closest thing to a rehearsal on the real stage with the real lights, but with an empty audience.
Make “flag on” and “flag off” a standard part of your definition of done. A feature is not finished until its tests pass in both states and the team has agreed on the date when the flag will be removed.
“How do you keep the number of test cases under control when many flags exist?” A solid answer: keep flags independent, test only realistic combinations, automate on/off runs in the pipeline, and delete flags promptly so combinations never accumulate.
17Flags Across Microservices, Web, and Mobile
A single switch is simple. A switch shared by dozens of services and millions of phones needs extra care.
Modern products are rarely one big program. A microservice architecture splits an application into many small services, each doing one job: one handles accounts, another handles payments, another handles inventory. A single click by a customer may travel through five or six of these services. That journey creates a new question for feature flags: if the feature is “on” for this customer, do all of those services agree?
flowchart LR A["Web or Mobile Client"] --> B["API Gateway"] B --> C["Order Service"] C -->|"passes flag decision with the request"| D["Payment Service"] C -->|"passes flag decision with the request"| E["Inventory Service"] D --> F["Receipt Service"]
Two ways to keep services consistent
The first approach is to let each service evaluate the flag by itself using the same user identifier and the same rules. Because hashing is deterministic, every service computes the same answer for the same user. The weakness is timing: for a second or two after a change, one service may have the new rules while another still has the old ones. For most features this tiny gap does not matter.
The second approach is to evaluate the flag once, at the entrance of the system, and pass the answer along with the request, usually as a small piece of metadata. Every service downstream simply obeys. This guarantees that one request sees one consistent story from start to finish, which is valuable for money-related features such as pricing or discounts. The price is slightly more plumbing in each service.
Why identity matters
Percentage rollouts depend on a stable identifier, such as a user ID. If one service uses an email address and another uses an internal account number, the same person can land in different buckets, and the experience becomes inconsistent. Agree on a single identifier across the company, and for visitors who are not signed in, use a stable anonymous ID stored with the visitor, such as one kept in a cookie.
The web browser
For websites, you can evaluate flags on the server before sending the page, which avoids a visible flicker where the old design appears for an instant and then switches to the new one. Evaluating in the browser after the page loads is flexible but can cause that flicker and exposes more information. Many teams use the server for layout-level decisions and the browser only for small interactive details.
Mobile apps: the hardest case
Mobile apps add a special problem: you cannot force users to update. A customer may run a version of your app that is six months old and does not even contain the new feature’s code. Flags cannot create code that is not there. So mobile flags are often combined with app version targeting, a rule like “enable only for version 8.2 and above.” Another challenge is poor connectivity: phones go offline in elevators and tunnels. Mobile SDKs therefore cache the last known answers on the device, and the code must still behave sensibly when it has never received an answer at all.
A kill switch on mobile only works if the shipped app already contains a check for that flag. Add flags around risky features before they ship in an app release, because you cannot add the safety switch afterward to code that is already on a million phones.
Data compatibility during rollouts
When a new feature changes how data is stored, flags create a period where old and new code run side by side. This means both versions must understand the same data. A safe technique is to first deploy code that can read both formats, then turn on writing in the new format for a small share of users, then widen it, and finally remove support for the old format. Doing this in the wrong order is a classic source of painful incidents, because rolling back the flag does not undo data that was already saved in the new shape.
18Advanced Topics: Consistency, Dependencies, and the Edge
For readers who want to go one level deeper into how flags behave inside large distributed systems.
Eventual consistency
In a distributed system, many machines hold copies of the same data, and updates do not reach every copy at the same instant. Flag rules follow this pattern, known as eventual consistency: after a change, all copies will agree, but for a brief window they may disagree. A well-run platform shortens that window to a second or two with streaming updates. Your design must tolerate the window. For a color change on a button, a one-second disagreement is harmless. For a billing change, it may not be, which is why critical flags often use the “decide once at the entrance and pass it along” approach.
Sticky assignment and its limits
Hash-based bucketing gives sticky assignments without storing anything. But it has limits. If you change the identifier you hash, for example by switching from an anonymous cookie to a signed-in user ID, the user lands in a new bucket and may flip between experiences. For serious experiments, platforms can also store assignments explicitly so that a person who joined group B stays in group B even if rules change. The cost is extra storage and more moving parts.
Flag dependencies and prerequisites
Sometimes one feature requires another to be on first. A “premium search filters” feature may need the new search backend to be active. Some platforms support prerequisites: flag B only evaluates as on if flag A is on. This is useful but dangerous if overused, because chains of prerequisites recreate the nested flag maze. Use them sparingly, document them clearly, and remove them as soon as the underlying feature is fully released.
Edge evaluation
Because CDNs and edge networks place small computing environments close to users, some platforms evaluate flags at the edge, in a server in the user’s own city. This brings two benefits: very low latency and fewer round trips to a central data center. It also allows a website to choose between page versions before the page is even built, which avoids flicker. The trade-off is that the rules must be copied to many locations, so update speed and secure handling of those rules become important.
Percentage rollouts with mixed traffic
A rollout of “10 percent” sounds exact, but real traffic is uneven. If one giant customer represents 40 percent of your traffic and happens to land in the rolled-out group, your “10 percent” may behave like 50 percent in terms of load. For business-to-business products, teams sometimes roll out by customer account instead of by individual user, so a whole company sees one consistent experience and so the effect of a problem is easier to understand and communicate.
Statistical honesty in experiments
Experiment flags carry a responsibility to count results correctly. Common pitfalls include stopping a test the moment the numbers look good, running too many comparisons and celebrating the one that looked lucky, and letting the same user appear in both groups. Remember that early results wobble randomly, just as a few coin flips may give four heads in a row. Decide the sample size and duration in advance, and respect them.
Judging an experiment too early is like tasting one spoonful of soup before the pot has been stirred. The top may be bland and the bottom salty. You need to wait until things mix and take enough spoonfuls before deciding whether the recipe works.
Progressive delivery
The wider practice of combining flags, canary releases, monitoring, and automatic rollback is often called progressive delivery. It treats a launch not as a single event but as a controlled journey with checkpoints, each guarded by measurements. Feature flags are the steering wheel of that journey.
19Governance: Keeping Flags Under Control as You Grow
A handful of flags can be managed from memory. Hundreds need rules, owners, and routines.
When a company is small, everyone remembers what each flag does. As teams multiply, memory fails, and flags that nobody understands start to accumulate. This is called technical debt, which is the hidden cost of shortcuts that must be repaid later with extra work. Flag governance means setting up simple, steady habits that keep this debt low.
A flag registry
Maintain one central list of all flags, with the owner, the type, the creation date, the purpose, the expected removal date, and links to the related ticket or design document. Most flag platforms provide this view automatically. The registry answers questions such as “Which flags are older than six months?” and “Which flags belong to the payments team?”
Ownership
Every flag must belong to a team and a named person. When people change teams, ownership must be reassigned. An orphaned flag is dangerous because nobody feels responsible for removing it, and nobody can answer questions about it during an incident.
Regular cleanup rituals
Many teams run a short monthly or quarterly “flag review.” They open the list, sort by age, and ask for each old flag: Is it fully on? Is it fully off? If so, delete it. Some teams assign a “flag cleanup” ticket automatically when a rollout reaches 100 percent. A few go further and set automated reminders or build checks that complain loudly when a flag passes its expiry date.
Separating short-lived and long-lived flags
Short-lived release and experiment flags should be clearly separated from long-lived operational and permission flags, in naming, in dashboards, and in review routines. Mixing them hides the old, forgotten flags among the permanent ones. A simple naming prefix or a tag in the platform is enough.
Safe change management
For high-impact flags, establish who may change them, what approvals are needed, and what must be announced. A good rule is to treat a production flag change like a small deployment: it has an owner, a reason, a way to check success, and a way to undo it.
Measuring the health of your flag practice
Teams that use flags well often track a few simple indicators: the total number of active flags, the age of the oldest release flag, the percentage of flags with a named owner, and how many flags were removed this month compared with how many were created. When creation consistently outpaces removal, debt is growing and it is time to slow down and clean up.
Context
A growing team creates flags quickly but removes them slowly, and nobody can explain half of the flags in production.
Decision
Require an owner, a type, and an expiry date when creating any flag, and hold a recurring flag review where expired release flags are deleted.
Consequence
Creating a flag takes a little more effort, but the codebase stays readable, incidents are easier to debug, and the number of possible code paths stays small.
20Real-World and Industry Examples
How well-known companies use the same simple idea at enormous scale.
Facebook: Gatekeeper and dark launches
Facebook built an internal system called Gatekeeper to control which users saw which features. Engineers could release a new capability to employees first, then a small percentage of users, then wider groups. The company also became well known for “dark launches,” where new back-end systems carried real traffic before any visible feature appeared, to prove they could handle the load. This helped Facebook ship changes very frequently while serving a huge audience.
Flickr: shipping many times a day
Flickr’s engineers described in 2009 how they deployed more than ten times per day by hiding unfinished features behind flags. Their message to the industry was simple: if you can separate deployment from release, you can deploy boldly and release carefully.
Netflix: experiments everywhere
Netflix is widely known for treating nearly every product change as an experiment. Different members can be shown different layouts, recommendation approaches, or artwork, with results measured before a change is rolled out to everyone. Flags and experiment assignments are the machinery behind that learning culture.
Amazon: constant deployment, careful exposure
Amazon has talked publicly about deploying code extremely often. At that pace, the business cannot let every deployment instantly change what shoppers see. Controlled exposure mechanisms, including flags and staged rollouts, let teams release changes to a portion of traffic first and widen them only when the numbers are healthy.
GitHub: shipping to staff first
GitHub has described using feature flags so that new functionality can be turned on for employees and selected users before the general audience. This allows the team to learn in production, gather feedback early, and keep releases small and reversible.
Microsoft: rings of exposure
Microsoft has documented a ring-based approach for products like Azure DevOps, where changes reach the internal team first, then progressively larger groups of customers. Flags help control which features are active in each ring.
Ride-hailing and delivery platforms
Companies such as Uber have discussed internal tools for dynamic configuration and experimentation. In businesses where a bad change can strand drivers or riders in one city, controlling a feature by city, by app version, or by percentage is a basic safety requirement.
21Build or Buy? Choosing Your Flag Tooling
Every team eventually asks whether a few settings in a config file are enough.
Feature flags can be implemented at several levels of ambition. The right choice depends on your size, your risks, and how many people need to control flags.
| Approach | Best For | Strengths | Limits |
|---|---|---|---|
| Simple configuration file or environment setting | Tiny teams, early products | Very simple and free | Changes need a restart or redeploy, no targeting, no audit trail |
| Database table with a small admin page | Small to medium products | Instant changes, full control | You must build targeting, rollouts, and safety yourself |
| Open-source flag platform that you host | Teams that want control and flexibility | Rich features without license fees | You operate and secure it, including its reliability |
| Commercial flag service | Growing and large organizations | Dashboards, SDKs for many languages, experimentation, support | Cost, vendor dependence, privacy review |
| Cloud provider feature flag tools | Teams already deep in one cloud | Close integration with existing cloud services | Features may be simpler, and moving later takes effort |
Questions to ask before choosing
How many people need to change flags, and are they technical? How quickly must a kill switch take effect? Do you need percentage rollouts and experiments, or only on-off switches? Where must your user data stay? Which programming languages do your services use? Who will be on call for the flag system itself? Honest answers usually point clearly to one of the options above.
Avoiding lock-in
Whatever you pick, put a thin wrapper between your code and the vendor’s SDK, as described in the patterns chapter, and look at open standards such as OpenFeature. Then, if your needs grow or prices change, switching tools is a project of days rather than months.
Start small. A modest, well-managed set of flags with clear ownership beats a sophisticated platform used carelessly. Add power only when a real problem asks for it.
22A Plain-Language Walkthrough: Your First Flag
Let us follow one small team through a complete, realistic example from idea to cleanup.
Meet a small team that runs an online bookstore. Their customers complain that searching for a book is slow and returns poor results. The team builds a new search engine and wants to replace the old one without risking sales. Here is how they use a feature flag, step by step, in everyday language.
Agree on the question
The team writes one sentence: “Will the new search engine return results faster without hurting book sales?” They also write down what failure looks like: slower pages, more errors, or fewer purchases after searching.
Create the flag with a safe default
They create a release flag named “new-search-engine,” assign an owner, and set the default to off. If the flag system ever fails, customers keep getting the old, trusted search.
Build both paths
The search page now contains two routes: the old engine and the new engine. The flag decides which one runs. Automated tests check both routes.
Deploy while dark
The new code goes live with the flag off. Nothing changes for customers. The team runs the new engine silently in the background for a sample of searches and compares its answers with the old engine, without showing them to anyone.
Try it as employees
They turn the flag on for staff accounts. Employees search for books and report oddities. Two bugs appear, both with unusual characters in book titles, and the team fixes them in one day.
Start the canary
They enable the new engine for 1 percent of visitors. Dashboards show that response time improves, but the error rate rises slightly for one language. They pause the rollout, fix the issue, and continue.
Widen gradually
Over the next week the rollout grows to 10, 25, 50, and finally 100 percent. At each step the team checks speed, errors, and purchases. The numbers hold steady, and the new engine slightly improves sales.
Keep the kill switch for a while
For two more weeks the flag stays at 100 percent so that a quick rollback is still possible if something unexpected appears during a busy holiday weekend.
Clean up
When everything has been stable for a month, the team deletes the flag check and the old search code, removes the flag from the platform, and closes the project. The codebase is back to one clean path.
Notice what never happened in this story. Nobody had to hold a stressful midnight launch. Nobody had to redeploy the whole site to undo a mistake. Customers never saw a broken page for longer than a small slice of them saw it for a few minutes. And the team ended with simpler code than they began with. That is the real promise of feature flags when they are used with care: smaller risks, faster learning, and calmer people.
Think of any change you worked on recently. Ask yourself three questions: What would failure look like? How would I notice it quickly? How would I undo it in under a minute? If any answer is unclear, a feature flag may be the missing piece.
23Frequently Asked Questions
24Summary and Key Takeaways
A feature flag is a small switch with a big effect. It lets teams put code into production without immediately exposing it, reveal features slowly while watching for trouble, and reverse mistakes in seconds. Behind this simple surface sits a thoughtful system: stored rules, fast local evaluation, stable hashing, careful delivery, monitoring, and good human habits. Used with discipline, flags make software delivery calmer and safer. Used carelessly, they leave a trail of confusing leftovers. The difference is not the tool but the habits around it.
Key Takeaways
- Flags separate deployment from release. Code can reach production safely while the feature stays hidden until the business is ready.
- There are four main types: release, experiment, operational, and permission flags, and each has a different lifespan and owner.
- Evaluation happens locally and instantly. SDKs keep rules in memory, update in the background, and use stable hashing so each user keeps the same experience during a rollout.
- Design for failure. Choose safe default values, keep last-known-good copies, and rehearse what happens when the flag service is unavailable.
- Roll out gradually and watch. Use dark launches, canaries, and kill switches, with health measures and rollback conditions decided in advance.
- Protect and record changes. Use roles, approvals, and audit logs, and never rely on a flag as a replacement for real authorization.
- Clean up relentlessly. Every release flag needs an owner and an expiry date, because forgotten flags become costly technical debt.