{"adoption": {"forks": 759, "observed_at": "2026-08-28T04:06:40.243951+00:00", "stars": 2349}, "canonical_url": "https://ross.abutalabs.com/products/abtestinggateway", "card": {"archived": false, "artifact_type": "service", "description": null, "domain": ["backend", "web-development", "microservices", "apis"], "enriched": true, "function": ["api-gateway", "routing", "proxy"], "health_score": 20, "homepage": null, "language": "Perl", "license": "MIT", "license_family": "permissive", "maturity": "maintenance", "member_repos": ["CNSRE/ABTestingGateway"], "name": "CNSRE/ABTestingGateway", "platform": ["self-hosted"], "pushed_at": "2018-10-14T07:05:17+00:00", "repo": "CNSRE/ABTestingGateway", "stars": 2349, "tags": ["gray-release", "canary-deployment", "ab-testing", "traffic-splitting", "nginx", "openresty", "ngx-lua", "redis", "load-balancing", "dynamic-routing", "layer7-gateway", "sina-weibo", "devops", "linux", "web-server"], "topics": [], "urls": [], "use_cases": ["dynamically split traffic between upstreams without restarting nginx", "run canary releases with policy-based gray deployment", "do A/B testing based on user id, ip range, or uid tail digits", "gradually route a subset of requests to a beta backend", "set up multi-level staged traffic diversion", "implement layer 7 load balancing with near-native nginx performance"], "what_it_is": "ABTestingGateway is a layer-7 gray-release (canary) gateway built on nginx and ngx_lua that dynamically routes requests to different upstreams according to diversion policies stored in Redis. Originally part of Sina Weibo's internal dygateway, it supports ip-range, uid-range, uid-tail, and specific-uid splitting, multi-level diversion, and runtime policy changes without restarts.", "when_to_avoid": ["You need an actively maintained gateway - the last release dates to 2018 and it targets older openresty versions with known lua-resty-core compatibility caveats", "Your stack is cloud-native or service-mesh oriented and you would prefer Envoy/Istio or a modern API gateway", "You cannot deploy Redis as the policy database", "You need gRPC or non-HTTP traffic splitting"], "when_to_choose": ["You already run nginx/openresty and Redis and need runtime-configurable canary or A/B traffic splitting", "You want diversion rules by ip range, uid range, uid tail, or specific uids that take effect immediately without restarts", "Forwarding performance close to native nginx matters to you", "You want to extend the system with custom Lua-based diversion strategies"]}, "data_as_of": "2026-08-30T08:39:29.467469+00:00", "members": [{"path": "/products/abtestinggateway", "repo": "CNSRE/ABTestingGateway", "role": "main", "score": 23}], "provenance": {"archived": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "artifact_type": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "description": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "domain": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "enriched": {"inputs": [], "kind": "computed", "method": "enrichment_status"}, "function": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "health_score": {"inputs": ["days_since_push", "days_since_release", "archived"], "kind": "computed", "method": "health_v1"}, "homepage": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "language": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "license": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "license_family": {"inputs": ["license"], "kind": "computed", "method": "license_family"}, "maturity": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "member_repos": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "name": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "platform": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "pushed_at": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "repo": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "stars": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "tags": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "topics": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "urls": {"kind": "observed", "observed_at": "2026-08-28T04:06:40.243951+00:00", "source": "github"}, "use_cases": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "what_it_is": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "when_to_avoid": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}, "when_to_choose": {"confidence": null, "enriched_at": "2026-08-30T02:36:56.734731+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "54b9b2cc59676d4fcdb11744f99e9da03ddfc0a5f947c02fec57f5ce4d31d76d", "fetched_at": "2026-08-28T04:06:40.243951+00:00", "kind": "readme", "missing": false, "url": "https://github.com/CNSRE/ABTestingGateway"}], "taxonomy_version": 1}}, "score": {"components": {"activity": 0, "longevity": 100, "rhythm": 8}, "computed_at": "2026-09-02T17:46:02.011165+00:00", "flags": [], "formula": "round(0.45*activity + 0.35*rhythm + 0.20*longevity); archived -> min(score, 10)", "inputs": {"age_days": 4063, "days_push": 2880, "days_rel": null, "gap_med": null, "n_releases_24m": 0}, "score": 23, "version": 2}, "staleness": {"enrichment_outdated": false, "low_confidence": false, "scrape_days": 9, "stale_scrape": false}}