Five questions to ask when a pull request adds a feature flag
A stale flag was a small change once. Someone reviewed the pull request, the feature looked fine, and the flag went in with it.
The flag is easy to miss. It is often two lines in a diff that is mostly the new behaviour, and that behaviour is what the review is for. Six months later the key is new-totals-2, and nobody is sure who owns it or what happens if it is turned off.
While the author still has the change open, renaming the key or adding the missing test takes a few minutes. These five questions are worth leaving on the pull request.
What to check
- Can I tell what it does from the key?
new-checkout-totalssays what it is.pay-flag-3does not. Keep the key in one constant so it is not copied as a string through the codebase. - What happens if the flag service is unreachable? Set the failover variant yourself. For a new calculation, that is usually the path already in production.
- Are both paths tested? If the tests only cover the on branch, add one for off. That is the branch you run when you roll the flag back.
- Is it evaluated once, at the right boundary? Read the flag where the request comes in, and pass the boolean down. Checking it again later buries the branch, and two call sites can disagree if the rules change during the request.
- Who removes it, and when? Write an owner and a cleanup ticket next to the declaration. Without a date, the flag stays after the rollout because deleting it feels riskier than leaving it.
A flag you can review from one file
The questions are easier to answer when every flag the service reads is declared in one module. This is the Featureflow Node SDK, with the flag registered up front and a failover written next to the key:
// flags.ts: every flag this service reads, in one place
import Featureflow from 'featureflow-node-sdk';
export const Flags = {
// owner: payments · remove after rollout: PAY-412
newCheckoutTotals: 'new-checkout-totals',
} as const;
export const featureflow = new Featureflow.Client({
apiKey: process.env.FEATUREFLOW_SERVER_KEY,
withFeatures: [
// No config? Stay on the current calculation.
new Featureflow.Feature(Flags.newCheckoutTotals, 'off').build(),
],
});
// checkout.ts: evaluate once, at the edge of the request
const useNewTotals = featureflow
.evaluate(Flags.newCheckoutTotals, user)
.isOn();
return useNewTotals ? calculateTotalsV2(cart) : calculateTotals(cart);From that file a reviewer can see the key, the owner, the cleanup ticket and the failover. When the flag comes out, a search for Flags.newCheckoutTotals finds every use, and the type checker complains about any you missed.
Put the questions in the pull request template
Paste the five questions into the pull request template under a heading like "Adds a feature flag?". They catch the problems that are annoying to fix once the flag has been live for a few months. Pair the template with the Featureflow audit log, which records changes to the flag after it ships, so you can follow it from the pull request that added it to the one that removed it. The docs cover pre-registering features and failover variants for each SDK.
Add the questions to the template. The next flag should at least have a readable name, a failover someone chose, and a ticket for taking it out.
#FeatureFlags#CodeReview#TechDebt#DeveloperExperience#ContinuousDelivery
Leave the flag questions on the pull request
Start free with Featureflow. Register a failover with the flag, and keep an audit trail of every change after it ships.
Start Now (Free)Related Articles
Retiring an API version without a surprise outage
A shutdown date hits every client at once, including the cron job nobody owns. Gate v1 with a per-client flag, brown out a slice of traffic, and turn a client back on if they still need the old routes.
Feature flags that only work when another flag is on
express-payments gets turned on for users who are still on the old checkout, and the page breaks while the dashboard looks healthy. Fold the two flags into one, or read both in a single function.
Turn expensive features down before the service falls over
Recommendations, search suggestions and big exports share the database with checkout. One flag with a few levels lets on-call drop the optional work during a spike, then put it back.