Builds a unified release-readiness gate that aggregates verdicts from any combination of k6 / JMeter / Gatling / Locust load runners and Lighthouse CI Web Vitals, applies severity-aware pass/fail thresholds, and emits a single go / no-go decision with per-metric deltas vs the main-branch baseline. Posts the delta as a PR comment when the team has the integration set up. Use when authoring a CI step that gates a deployment on cross-runner perf compatibility.
68
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Deep reference for perf-budget-gate SKILL.md. Consult when wiring the gate
into CI, mapping each runner's output artifact, or setting per-metric budgets.
Each runner writes a machine-readable artifact the gate flattens into the
unified metric record. Persist each as a CI build artifact (if: always()) so
the gate input is reproducible and triageable.
| Source | Artifact | Produce with | Yields |
|---|---|---|---|
| k6 | summary.json | k6 run --summary-export summary.json | Per-metric values + threshold pass/fail. |
| JMeter | results.jtl + report/statistics.json | jmeter -n -t plan.jmx -l results.jtl -e -o report | Per-sampler percentiles + counts. |
| Gatling | js/stats.json under target/gatling/<sim>-<ts>/ | Gatling run (writes the HTML report bundle) | Per-request percentiles + assertion outcomes. |
| Locust | <prefix>_stats.csv | locust --csv <prefix> --headless | Per-endpoint percentiles. |
| Lighthouse CI | .lighthouseci/lhr-*.json | lhci autorun / lhci collect | Per-URL audit results including Web Vitals. |
Back-end latency budgets come from the team's NFRs; the Core Web Vitals "good" thresholds are the canonical front-end defaults (web-vitals).
| Metric | Budget | Severity (typical) |
|---|---|---|
p95_latency_ms | team NFR (e.g. 500) | blocker |
error_rate | 0.01 | blocker |
lcp_ms (Largest Contentful Paint) | 2500 | blocker |
inp_ms (Interaction to Next Paint) | 200 | blocker |
cls (Cumulative Layout Shift) | 0.1 | blocker |
| Lighthouse category score | advisory | warn |
Assert on individual Web Vitals, not the aggregate Lighthouse performance score - the score conflates LCP / INP / CLS, so one bad vital tanks it uninterpretably.
Run each runner, upload its artifact, then run the gate as the final step. The
gate writes its markdown summary to $GITHUB_STEP_SUMMARY and exits non-zero
on a no-go verdict, which fails the job (gha-summary).
# .github/workflows/perf-gate.yml
- name: k6
run: k6 run --summary-export k6-summary.json load.js
- name: Lighthouse CI
run: npx lhci autorun
- name: Upload perf artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: perf-artifacts
path: |
k6-summary.json
.lighthouseci/
- name: Perf budget gate
run: python scripts/run_perf_gate.py >> "$GITHUB_STEP_SUMMARY"Store the last green main-branch record set as a baseline artifact uploaded on every main-branch run, so per-PR deltas compare against a real baseline rather than the previous PR.