I’ve been poking at the OpenFeature website’s list of providers, with Claude doing much of the code-reading and running of experiments. OpenFeature is the vendor-neutral API for feature flags, and its site lists around sixty providers. A provider is the adapter between the OpenFeature SDK in your app and some flag system behind it. The list says which languages each provider supports. It doesn’t say anything about what’s behind it, even if it does give a breakdown between server or client emphasis for the tech. Claude has also helped with the drafting of this blog entry - and attempting to keep my voice.

My former colleague Pete Hodgson is involved in the OpenFeature effort. He wrote its 2022 launch announcement and sits on its governance committee. Pete also wrote the Feature Toggles article for Martin Fowler’s site, which categorizes toggles by purpose (release, experiment, ops, permissioning), and a five-minute intro to OpenFeature.

The taxonomy I’d teach way back was by when a toggle takes effect: build time, boot time, or run time (“hot”). My 2007 Branch by Abstraction article’s case-study had toggles, in XML back then. It was not drilled into blog entry cos that was about non-branching strategy. My 2019 thoughts on toggles goes into the three. Everything below is about the hot kind, and how hot they really are.

Re OpenFeature’s list of alternates, I had two questions. As ever, the first was whether any of them use version control as the backing store for toggles. Consul had git2consul years ago, and I said back in 2019 that the service-discovery and config-distribution tools should leverage source control. The second question came later: once a toggle is flipped, how long until a running app sees it?

Method

Provider SDKs just call an API, so they don’t reveal where flags are stored. We shallow-cloned the open-source servers behind the providers, and then the SDKs and OpenFeature providers, and read the code: docker-compose files, database drivers, storage packages, polling defaults, streaming code. Every figure below is a code default at the start of November 2026, with a file and line behind it. Mostly the Node provider plus one other server language (Java or Go) per system. Closed-source SaaS offerings (LaunchDarkly, Split, ConfigCat, DevCycle, Statsig and so on) are absent, because there was no code to read.

Not everything on the list is a server

Several entries are flag evaluators. You keep the flags somewhere yourself and they read from there:

  • GO Feature Flag’s own README says “no backend to run. No database”. It reads a YAML/JSON/TOML file from wherever you put it: a file, HTTP, GitHub/GitLab/Bitbucket, S3, GCS, Azure Blob, a Kubernetes ConfigMap, MongoDB, PostgreSQL, Redis. All of those are read-only to it. It’s an aggregator more than a flag system, and how a level-two support person would flip a toggle is left to you and whatever store you chose. Three days ago they previewed GO Feature Flag Studio, an optional UI aimed at exactly that person. It stores flags in PostgreSQL, not Git, and isn’t released yet.
  • Featurevisor is a flag compiler. You keep flag definitions in a Git repo, CI compiles them into JSON “datafiles”, and you publish those to a CDN or static host. There is no server as such, but it fits a bunch of CI/CD ideals.
  • flagd is an evaluation daemon (and the OpenFeature project’s own). It reads from files, HTTP, gRPC, Kubernetes custom resources, S3, GCS or Azure Blob.
  • Ageris and MongoDB + Rules are libraries inside your app, reading files and a Mongo collection respectively.

Backing stores of the actual servers

System Backing store
Bucketeer MySQL or PostgreSQL
FeatBit MongoDB or PostgreSQL
Flagsmith PostgreSQL
flagtide PostgreSQL
Flipt v2 Git
GrowthBook MongoDB
PostHog PostgreSQL
Superposition PostgreSQL
Unleash PostgreSQL

So one out of nine. PostgreSQL is the default answer for this category of software.

Git as the store: Flipt v2

What I’m interested in is a round trip. The flag system’s own editing app commits and pushes when someone flips a toggle in the UI. And a suitably authorized person can clone the same repo, change a set of flags in their editor, commit and push, and the system picks it up. That second path is how you batch changes to sets of flags, review them, and get history, blame, diffs and reverts for free. S3 has versioning if you turn it on. An HTTP endpoint has none.

Flipt v2 does both directions. Flipt v1 had SQLite (the default), PostgreSQL, MySQL, CockroachDB and LibSQL, plus read-only Git, OCI and object-storage sources. v2 dropped the databases. A UI or API edit becomes a commit that is pushed to the remote. Flipt also polls that remote every 30 seconds by default (poll_interval, down to 1s) to pick up commits pushed from elsewhere. If the remote moved on, a UI save re-fetches and re-applies the edit on top rather than clobbering someone’s push. Flipt reads the whole repo at one commit, so a batch of flag changes in a single commit lands all at once. Branches can be environments too.

Two caveats. Flipt v2’s server is under the Fair Core License (FCL-1.0-MIT), which is source-available and converts to MIT later, not open source today. And some Git conveniences are in the commercially licensed part: proposing pull requests from the UI, and a webhook from the Git host that triggers an immediate fetch rather than waiting for the next poll.

GO Feature Flag and Featurevisor use Git too, but only to read. You’re expected to edit with ordinary Git tools. That’s fine for developers. It may be OK for support people at 3am, too, but it might not be so smooth for business people if they are encouraged to make changes in certain situations. I blogged previously about pretty editor panels for commodity VCS web-UIs: an app-config workflow using SCM (2012), then Perforce as a datastore with client-side MVC (2013), custom JSON editors for GitHub via a Chrome extension (2015), and RhodeCode and Angular as an editor for a config-as-code system (2016). The business-user angle is in Rules Engines Suck Too If They Are Not Backed By Source-Control.

How long does a flip take to land?

There are two hops: from the change to the flag server serving it, and from the server to the running app via the OpenFeature provider. The app gets changes in one of three ways: it asks the server on every evaluation (fresh, but a network call per flag check), it polls for the whole rule set and evaluates locally, or the server pushes changes over a stream. These are defaults, not best-case configurations.

System Server-side app, default worst case How Push/stream option Browser provider default
Bucketeer under a second server evaluates each call SSE exists, server SDKs don’t use it  
FeatBit under a second WebSocket push on by default, free  
Flagsmith next call server evaluates each call SSE, Enterprise only never refreshes
flagtide (no server-side provider)   WebSocket, free ~100ms (their benchmark, p95)
Flipt v2 UI edit: immediate. Push to the remote: up to 30s server evaluates each call Git webhook is paid. A free SSE stream exists, which the OpenFeature providers don’t use never refreshes
GrowthBook never, until restart fetched once at startup SSE via GrowthBook Cloud or their MIT proxy  
PostHog 30s (Node), 5 min (Go) with a key. Seconds without polling, or per-call without a key none never refreshes
Superposition JS: never, until restart. Java: whatever you set local evaluation none  
Unleash ~16s (15s poll, ~1s server) polling Enterprise only (plus a paid Edge add-on, beta) 30s
flagd under a second for gRPC, Kubernetes and watched files. ~5s for HTTP/blob streamed to the provider built in  
Featurevisor CI + CDN cache + your own poll. Never if you don’t write that poll you call setDatafile()   same
Ageris ~10s (Spring Boot/Helidon) re-reads files    
MongoDB + Rules under a second MongoDB change streams, falls back to 5s polling built in  

“Never refreshes” for browser providers means until the page reloads, the user identifies, or the evaluation context changes, depending on the product.

What stands out

“Never” is a common default. GrowthBook’s JS and Java OpenFeature providers fetch once at startup and keep that. So does Superposition’s JS provider. Several browser providers don’t refresh either. That’s fine for a release toggle you flip once and then remove. It’s not fine for an ops toggle or kill switch that someone flips during an incident and expects to take effect. You have to opt into polling or streaming, and you should know which you’ve done before you need it.

Push is often the paid feature. Unleash, Flagsmith and Flipt’s Git webhook are commercial. FeatBit, flagtide, flagd and GrowthBook (via its proxy) have it free.

Asking the server every time is the freshest. Bucketeer, Flagsmith and Flipt default to remote evaluation for server-side apps, so a flip is visible on the next evaluation. You pay a network call per flag check.

Client-side evaluation publishes your rules. Anything a browser downloads is public, and products that evaluate in the browser ship the rules, not only the outcomes: segments, attribute conditions, rollout percentages. Featurevisor has tags and per-target builds to trim what each client receives, but nothing is encrypted. Products whose server evaluates and returns results keep the rules private.

And a bug

While reading MongoDB + Rules, Claude noticed that in single-document mode the change-stream filter lists "update " with a trailing space. MongoDB reports "update", and the library’s own client writes flags with $set, so edits made that way would never reach running apps, and nothing errors to trigger the polling fallback. The default all-documents mode is spelled correctly. That’s one for an issue on the repo.

Where this leaves me

For Git (or any VCS) as a first-class, round-trip toggle store, Flipt v2 is the one for now. Well, after reading the licensing it may be. Everything else that manages its own flags uses a database, mostly PostgreSQL.

If you pick differently, check the refresh defaults of the provider in the language/platform you’re using, and test a flip end to end before an incident does it for you.

A digression, sorry!

I saw that Unleash came up on Hacker News again: We’ve built an open-source feature flag server for 11 years. 156 points and 104 comments in a day. Unleash had been posted five times before, between 2020 and this year, as “Unleash – an open source feature toggle service”, “Show HN: Unleash Open-Source feature flag solution” and similar. Those got one to three points each.

Hacker News submissions of github.com/unleash: the latest with 156 points and 104 comments, five earlier ones with one to three points each

Same repo, so why the difference? Luck in the first hour plays a big part on HN, and Ivar (the creator) being in the thread answering helps. But I think the title did a lot. The grammar is slightly off: “built” says finished, “for 11 years” says ongoing. And it sets up a point and never makes it: for 11 years… and? Here’s what we learned? We’re shutting down? Ask us anything? I doubt any of that was intended, but together it’s accidental catnip for HN frequenters. The earlier titles were complete and coherent, and gave nobody anything to resolve. This one left a gap, and readers filled it with their own endings in the comments: you could have used Redis, LLMs make this obsolete, AGPL isn’t really open source, LaunchDarkly is somehow worth $3B. And I should confess I’m not immune: that catnip is how I ended up here this morning, reading the source of a dozen feature flag systems instead of whatever I’d planned to do.

To come back for usefulness from this digression, somebody in there did ask how clients keep their local evaluation up to date. I have a table for that now, above.



Published

November 7th, 2026
Reads:

Categories