Repository navigation
Labels
Description
Feature Description
k6 has no shared way to put a feature behind a named, discoverable flag. Anything experimental or optional ends up with its own ad-hoc env var or option, with no common naming, no lifecycle, and no single place to list what exists. As more in-progress features land, this gets harder to reason about for both users and maintainers.
Suggested Solution (optional)
Add a generic feature-flag system:
- A
--featuresflag onk6 runandk6 cloud run, plus afeaturesfield in the config file. Precedence: command line, then environment, then config file. - A
k6 featurescommand that lists every flag and its lifecycle stage (experimental, GA, deprecated), with a--jsonoption. - Active flags carried into the run environment so they reach archives and cloud/distributed workers, and surfaced as
k6_feature_<name>metric tags. - A retirement path for old env vars: an alias can be honored (still works, warns), tombstoned (errors), or removed (ignored).
native-histogramsas the first real flag, replacing theK6_PROMETHEUS_RW_TREND_AS_NATIVE_HISTOGRAMenv var (kept as a deprecated alias).
Current spec match
| Scenario | Result |
|---|---|
| CLI > env > JSON precedence | ✅ |
Multiple --features flags merge/dedup |
✅ |
Empty --features "" overrides everything |
✅ |
K6_FEATURES="" + legacy alias → union, alias activates |
✅ |
Falsy legacy alias (=false) → env not supplied, JSON consulted |
✅ |
| Non-kebab input treated as Unknown (not hard error) | ✅ |
| Unknown flag: ERROR log, exit 0, not in activation set | ✅ |
| Experimental activation: INFO log | ✅ |
| Deprecated activation: WARN log | ✅ |
| GA activation: INFO "please remove" log | ✅ |
| GA forced true without activation: no log, no tag | ✅ |
| CLI overrides JSON; GA stays on regardless | ✅ |
| Legacy alias: dual log (alias WARN + canonical INFO) | ✅ |
| Legacy alias: telemetry uses canonical name | ✅ |
| Phase-1 alias with dangling canonical: WARN + ERROR | ✅ |
| Phase-2 tombstoned: ERROR only, no activation | ✅ |
| Phase-3 removed: silent | ✅ |
Tag: k6_feature_<snake>=true per activated feature |
✅ |
| Tag: unactivated GA emits no tag | ✅ |
Tag: kebab → snake (native-histograms → k6_feature_native_histograms) |
✅ |
k6 features table: sorted Experimental → Deprecated → GA |
✅ |
k6 features --json: exact keys name/lifecycle/description |
✅ |
Distributed exec: archive bakes K6_FEATURES |
✅ |
Worker replay: reads from baked env (is_archive=true), not process env |
✅ |
| Version skew: unknown feature on worker → ERROR, continues | ✅ |
| Telemetry: canonical names reported | ✅ |
noCopy: go vet catches value copies |
✅ |
Activated() returns defensive copy |
✅ |
Stale k6_feature_* run tags stripped and replaced |
✅ |
remotewrite gets NativeHistograms=true when feature active |
✅ |
remotewrite gets NativeHistograms=false when feature absent |
✅ |
Activity
[-]Implement feature flags[/-][+]Feature flags[/+]