Flagr is an open-source Go service for feature flags, A/B testing, and dynamic configuration. One primitive β the flag β covers all three: a decision point in your code that the evaluation engine resolves at runtime based on who is asking.
It exists to decouple deploy from release β turn a feature on for one user, a thousand, or nobody, without redeploying. Run experiments and trust the numbers. Change configuration without a code change or a restart.
openflagr/flagr is the community-driven home of Flagr, advancing development
beyond the original checkr/flagr.
https://openflagr.github.io/flagr
Developers: clone the repo and run make help for build, test, and UI commands (single entrypoint for CI and local work).
| Page | Content |
|---|---|
| Home | Quick start, dev, testing, deploy |
| Overview | Concepts, running example, architecture |
| Use Cases | Feature flags, A/B testing, dynamic configuration |
| Debug Console | UI evaluation testing |
| Server Configuration | Environment variables, DB, auth, recorders |
| JSON Flag Source | GitOps, JSON format, validator |
| Notifications | Webhooks on flag changes |
| Exposure Logging | POST /exposures API |
| Data Recorders & A/B Analysis | Kafka, Kinesis, Pub/Sub; sample consumer; A/B analytics |
| Datar Analytics | In-process eval aggregates |
| API Reference | Swagger/OpenAPI spec |
- Feature flags β binary on/off, kill switches, targeted rollouts by audience
- Duplicate flag β clone variants, segments, constraints, distributions, and tags to a new flag (
POST /flags/{id}/duplicateor Flag Management on flag detail) - A/B testing β multi-variant experiments with deterministic, sticky assignment
- Dynamic configuration β per-variant JSON attachments, no redeploy or restart
- GitOps / Flags-as-code β load flags from JSON or HTTP; manage in Git, validate in CI, rollback with
git revert - Exposure logging β
POST /exposuresfor client-reported impressions, the trustworthy A/B denominator - Webhook notifications β HTTP POST on every flag change, with retry and backoff
- Multi-database β SQLite (dev), MySQL, PostgreSQL, and JSON sources
- Vue 3 UI β TypeScript management UI (Vite, typed REST via
ApiResult); seemake helpforbuild-ui/test-e2e
docker pull ghcr.io/openflagr/flagr
docker run -it -p 18000:18000 ghcr.io/openflagr/flagr
# Open the Flagr UI
open localhost:18000Or try the hosted demo at https://try-flagr.onrender.com (cold starts may take a moment):
curl --request POST \
--url https://try-flagr.onrender.com/api/v1/evaluation \
--header 'content-type: application/json' \
--data '{
"entityID": "127",
"entityType": "user",
"entityContext": { "state": "NY" },
"flagID": 1,
"enableDebug": true
}'Flagr has three components:
- Evaluator β serves evaluation from an in-memory cache of all flags. The cache refreshes periodically (default 3s) and short-circuits when nothing changed, so evaluation never touches the database on the request path.
- Manager β the CRUD gateway; all flag mutations flow through here.
- Metrics β fans evaluation and exposure events out to your data pipeline (Kafka, Kinesis, Pub/Sub) or the built-in Datar aggregates. Recording is asynchronous, so a slow backend never stalls an evaluation.
See the architecture overview for diagrams, request flows, and the deterministic bucketing algorithm.
Tested with vegeta β 2,000 req/s sustained, sub-millisecond
median latency:
Requests [total, rate] 56521, 2000.04
Duration [total, attack, wait] 28.26s, 28.26s, 365.53Β΅s
Latencies [mean, 50, 95, 99, max] 371.63Β΅s, 327.99Β΅s, 614.92Β΅s, 1.39ms, 12.50ms
Success [ratio] 100.00%
Status Codes [code:count] 200:56521
| Language | Client |
|---|---|
| Go | goflagr |
| JavaScript | jsflagr |
| Python | pyflagr |
| Ruby | rbflagr |
openflagr/flagrβ Apache 2.0checkr/flagrβ Apache 2.0 (original project)
