Building with Feature Flags 2

Backend services usually have a different feature flag problem from browsers. They may process thousands of requests per second, run for days, serve many tenants, and sit directly on critical business paths.

Initialize once, evaluate many times

A long running service should normally initialize its feature client as part of application startup and reuse it rather than creating a client for every request.

service startup
   ↓
initialize provider
   ↓
receive or refresh configuration
   ↓
request 1 → local evaluation
request 2 → local evaluation
request 3 → local evaluation

This pattern applies to Java services, Node.js APIs, Python services and .NET applications even though the lifecycle hooks differ.

Prefer local evaluation on hot paths

If every business request requires a synchronous network call to a feature flag control plane, the feature system becomes part of your request latency and availability path.

Most mature server SDKs therefore keep a local representation of the flag configuration and evaluate against it in process. The control plane distributes configuration; the application performs the decision.

Defaults are part of the design

Every flag evaluation should have a deliberate fallback value. The choice depends on what the flag controls.

FlagPossible safe default
new optional UI capabilityoff
new payment pathexisting proven path
emergency dependency kill switchdepends on incident design
security sensitive capabilityusually fail closed

A default should not be chosen merely because false is convenient.

Keep evaluation context close to the request

Backend targeting may use tenant ID, user ID, region, channel, product tier, API version, or another attribute already present in the request context.

A clean implementation creates the evaluation context at a defined boundary rather than reconstructing it differently in many business classes.

Do not scatter flag checks everywhere

This is tempting:

if flagA ...
if flagB ...
if flagC ...

spread through controllers, repositories and domain logic.

Prefer placing a feature decision near the boundary where behavior actually changes. If a new pricing engine replaces an old one, choose the engine once and then execute normal business logic inside the selected implementation.

request
   ↓
resolve pricing strategy
   ↓
old engine OR new engine
   ↓
normal domain flow

Operational flags need stronger treatment

A backend kill switch can disable a dependency, queue consumer, cache path or expensive calculation. Those flags may be used during incidents, so propagation speed, auditability, permissions and provider outage behavior matter more than developer convenience.

What to test

  • enabled and disabled paths
  • targeting by tenant and user context
  • startup when the provider is unavailable
  • continued service using cached configuration
  • behavior when configuration changes during traffic
  • performance at realistic request volume
  • removal of the old code when a temporary rollout is complete

For backend services, the goal is not merely to evaluate a flag. It is to make that evaluation cheap, resilient, understandable and easy to remove when its job is finished.


Feature Flags series

← Feature Flags in Frontend Applications   Feature Flags in Serverless Applications →