Feature flag service architecture.
Evaluation has to be local and instant, because a flag check sits in the hot path of code that would otherwise not make a network call at all.
The components
Every row below is read from the graph that produced the diagram above, so the two cannot disagree.
| Component | Tier | Why it is there |
|---|---|---|
| Client SDKs | Client | Evaluate locally, never block on a network call |
| CDN | Edge | Serves the ruleset, cached at the edge |
| Streaming endpoint | Edge | SSE push, so a kill switch is instant |
| Flag API | Application | Supporting component |
| Rule compiler | Application | Targeting rules to a payload SDKs can evaluate |
| Audit log | Application | Who flipped what, and when |
| Exposure events | Application | Which variant each user actually saw |
| Postgres | Data | Supporting component |
| Redis | Data | Supporting component |
| Kafka | Data | Supporting component |
| Warehouse | Data | Experiment analysis, not the serving path |
Design decisions worth arguing about
A diagram shows what was chosen. It does not show what it cost, and that is usually the part that matters in a review or an interview.
Evaluate in the SDK, never over the network
A flag check happens in code paths that run thousands of times a second, so a network call per evaluation is out of the question. The SDK holds the compiled ruleset in memory and evaluates locally in microseconds. The cost is that every client is briefly out of date after a change, and that the ruleset must be small enough to hold and cheap enough to evaluate.
Streaming, because a kill switch is the point
Polling every thirty seconds is fine for a gradual rollout and useless for the case the product actually exists to serve, which is turning something off immediately during an incident. A streaming connection pushes changes in under a second. The cost is holding an open connection per client process and a fallback path for networks that will not permit it.
The CDN is the availability story
If the flag service is down and SDKs cannot fetch a ruleset, applications either fail or run on stale defaults. Serving the ruleset as a static artifact from a CDN means the read path survives an outage of everything else you operate. It also means a change is not live until the cache expires or is purged, so purge behaviour becomes load-bearing.
Exposure events are a separate system
Knowing which variant a user actually saw is what makes experiments analysable, and it is high-volume telemetry with nothing in common with flag serving. Keeping it on its own path means an analytics outage cannot affect evaluation. The consequence is that experiment results lag, sometimes by hours, which surprises people expecting a live dashboard.
How it changes with scale
Evaluation cost is zero to the service, since it happens in the client. What scales with usage is exposure event volume, which grows with traffic times flag count and quickly exceeds every other write in the system. Ruleset size grows with flag count and matters because it is held in memory in every process.
Where it breaks first
A flag that never gets cleaned up. The technical system stays healthy while the ruleset accumulates hundreds of permanently-on flags, each one a branch in the code nobody removes. The failure is organisational and shows up as evaluation latency and unreadable code rather than as an outage, which is why flag expiry dates and an owner per flag matter more than any part of this diagram.
Draw this yourself
Open the Diagram tab and describe the system. The agent emits a semantic graph rather than coordinates, so you can edit the components and the layout re-solves instead of drifting.
When the shape is right, Implement in code turns the canvas into a markdown specification, every component, every relationship and the notes, and starts a real turn in the Code tab with it.
Questions about this design
More templates
- URL Shortener System DesignThe canonical read-heavy system: roughly a hundred reads for every write, and a redirect that has to be fast enough that nobody notices it happened.
- Chat Application System DesignLong-lived connections change everything: the hard part is not storing messages, it is knowing which of your servers is holding the socket you need to write to.
- Payment System DesignThe only system on this list where being approximately right is indistinguishable from being wrong, and where the provider, not you, holds the truth.
- RAG Pipeline ArchitectureAlmost every RAG system that disappoints is failing at retrieval, not generation, and the architecture is what decides whether you can tell.