3 ms·
Hi, I'm at LaunchDarkly, a commercial feature flag service. I'll explain how our flags work, which is different from more traditional implementations. But firs
by yoz 5y ago
Hi, I'm at LaunchDarkly, a commercial feature flag service. I'll explain how our flags work, which is different from more traditional implementations.
But first, as mentioned elsewhere, using a feature flag in code _usually_ looks something like...
flagValue = getFlag(FLAG_NAME, user_context)
if (flagValue == true)
... do the thing
else
... do the other thing
So, a couple of those traditional implementations:
1. Environment variables: Good for fast checking; no I/O needed. But if you need to flip a flag, your code won't pick up that change without restarting, maybe even redeploying. Many uses for flags, such as user enablements and kill switches, rely on flag changes being picked up immediately. Plus, this has no targeting capabilities: if a flag is on or off, it's on or off for _everyone_.
2. Request on demand: You store the flags in a database or other external system, then fetch the value when the code evaluates it. This means that flag changes get picked up without restarts, at the cost of blocking I/O. So, the more flags you have, the worse your performance gets. Not great. But if you send the user_context with the flag request, your flag service can do targeting (different flag values for different users)
3. Background polling: Similar to request on demand, except that you keep an in-memory cache so that flag evaluation happens instantly, and that cache is kept up to date with a background thread that periodically checks the flag service. Better performance than request on demand, but updates have more latency. Increasing the poll rate reduces latency at the cost of load on the flag service. Also, the cache will presumably only cache the flag value for the current user, unless you want to build a rule engine which runs locally.
Here's how LaunchDarkly does it:
Our SDK connects at app startup and downloads the flag data. If it's a server-side SDK, that data will include all the targeting rules. (Yes, we built a rule engine that runs locally. It's pretty powerful.[1]) The SDK caches that data so flags can be evaluated for all user contexts without making a request. However, the SDK then keeps a persistent connection open to our server (or a local proxy). When a flag changes, our server pushes the update through that connection, which updates the SDK's cache instantly. At present, flag updates take about 200ms to propagate to SDKs, usually less.
More technical info here: https://docs.launchdarkly.com/sdk/concepts/contributors-guide https://docs.launchdarkly.com/sdk/concepts/contributors-guid...
[1] https://docs.launchdarkly.com/sdk/concepts/flag-evaluation-rules https://docs.launchdarkly.com/sdk/concepts/flag-evaluation-r...