K6 Test Maintenance
Grafana LabsOfficialPublished by Grafana Labs
- Skill
- Workflow
- Software development
- Apache-2.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The k6-test-maintenance skill provides a structured, safety-first approach to updating existing k6 performance tests. It covers five core maintenance tasks: threshold tightening, version migration, service change adaptation, code refactoring, and best-practices auditing. The skill enforces a strict behavior-aware change control process, distinguishing between syntactic changes (which can be applied automatically) and behavioral changes (which require user review and confirmation). It integrates with k6-manage and Grafana Cloud APIs to ensure that all modifications are validated through parse-checks and cloud-based smoke tests before being finalized.
What it does
- Tightens threshold values based on historical trend data and metric observations.
- Migrates scripts to newer k6 versions by identifying deprecated APIs and patterns.
- Adapts existing test scripts to accommodate changes in the underlying service.
- Refactors test code for improved cleanliness and adherence to current best practices.
- Audits scripts against official k6 documentation to ensure optimal performance and reliability.
- Validates all changes using a multi-stage process including parse-checks and cloud smoke runs.
When to use it
- When a test is failing after a service deployment or infrastructure change.
- When you need to update thresholds to reflect current performance trends.
- When migrating legacy scripts to a newer k6 release.
- When you want to refactor or modernize your existing test codebase.
- When you need to ensure your scripts align with current k6 best practices.
Advantages
- Reduces risk by classifying changes as syntactic or behavioral before application.
- Prevents breaking CI gates or SLOs through rigorous verification recipes.
- Grounds all recommendations in official k6 documentation and API references.
- Provides a safe, standardized workflow for cloud-hosted script management.
- Minimizes manual effort by automating syntactic refactoring and validation.
Usage examples
- “My k6 test is failing after the latest service deployment, can you fix it?”
- The agent will analyze the service changes, identify the impact on the test script, propose necessary adjustments, and guide you through the verification process.
- “Tighten my p95 thresholds based on the last 30 days of data.”
- The agent will query historical metrics, calculate appropriate new thresholds, present a pass/fail impact table, and apply the changes upon your approval.
- “Migrate this script to k6 v2.”
- The agent will identify deprecated APIs, propose the required syntax updates, and perform a cloud smoke test to ensure the migrated script functions correctly.
- “Refactor my k6 test to follow best practices.”
- The agent will audit the script for common issues, suggest cleaner patterns, and provide a diff for any behavioral changes before applying them.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/grafana/k6-test-maintenance/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip k6-test-maintenance.zip -d .agents/skills
Documentation by Grafana Labs
k6 Test Maintenance
Maintain, fix, and improve existing k6 test scripts. Five maintenance tasks,
each with a step-by-step procedure in references/workflows.md:
Threshold tightening -- adjust threshold values based on observed metrics
Version migration -- update scripts for new k6 releases
Service change adaptation -- fix tests when the underlying service changes
Refactoring -- clean up and modernize test code
Best practices audit -- check scripts against current k6 best practices
Core principle: behavior-aware change control
Classify every proposed change by whether it alters the test's runtime behavior:
Syntactic (behavior unchanged): the k6 runtime produces identical metrics, pass/fail results, and endpoints. Examples: rename a variable,
let→const, remove unused imports, update comments, reformat. Apply directly.Behavioral (behavior differs): anything affecting metrics, pass/fail, timing, request targets, or load shape. Examples: threshold value changes, adding
sleep(), endpoint URL updates, check rewrites, scenario changes, new thresholds. Always present as a diff with rationale and require confirmation.
The threshold for "behavioral" is deliberately low. If in doubt, treat it as behavioral and ask -- a trivial-looking threshold change can cascade to CI gates, SLO calculations, and alerting.
Dependencies
k6-manage-- fetch and edit GCk6-hosted scripts safely (§5: GET, backup, edit, validate, PUT, verify by sha256). Read it before touching any cloud-hosted script.gcx-- sole tool for Grafana Cloud API access.mcp-k6 tools --
validate_scriptandget_documentation. Check availability first; fall back tok6 x docsif absent.k6 x docsCLI -- documentation lookup when mcp-k6 isn't configured.k6CLI -- local validation (k6 inspect,k6 run).
Validation loop (every edit)
Every workflow produces a modified script. Never present or PUT an unvalidated script -- run this loop, fixing and re-running until it passes:
Parse-check:
k6 inspect <script>-- catches syntax errors, invalid options, broken imports. Works on all types including browser tests (no browser needed). If mcp-k6 is available, also runvalidate_script.Local smoke (non-browser, service reachable):
k6 run --vus 1 --iterations 1 <script>.Classify the change (below) and verify per the matrix -- recipes in
references/verification.md.Cloud-hosted scripts: apply via the k6-manage §5 safe-edit recipe (GET → backup → edit → validate → PUT as
application/octet-stream→ sha256-verify).
Change classification
Class A -- declarative-config only. The diff is confined to
options.thresholdsor similar declarative fields that don't alter what the k6 runtime executes; the bytes insidedefault function, imported modules, and check predicates are byte-identical. Example:p(95)<500→p(95)<420.Class B -- runtime logic changes. Any change to
default function, imports, helper modules, request URLs, check predicates, or toscenarios.*.vus/iterations/duration/executor(which alter load shape and metric distributions). Example: changing a URL, adding a check, rewriting auth, switching executors.
When in doubt, treat as Class B.
Verification matrix
| Class | Test duration | Verification |
|---|---|---|
| A | any | sha256 + k6 inspect + historical pass/fail prediction. No cloud run needed. |
| B | short (< 5 min) | sha256 + k6 inspect + full cloud run (k6-manage §11). |
| B | long (≥ 5 min) | sha256 + k6 inspect + local 1-iteration smoke + k6 cloud run of a local copy with --vus 1 --iterations 1. PUT to the saved test only after the cloud smoke passes. |
Verification depth depends on the change class, not the test's duration -- most
edits don't need a full run, and production tests may run for hours. Per-class
recipes (Class A prediction table, Class B short/long, edge cases like scenario
changes and loosening) are in
references/verification.md.
Documentation lookup
Before proposing any change that touches k6 APIs, imports, or patterns, confirm it against current docs and cite the source in your report -- this grounds recommendations in the real API, not stale model knowledge. Look up in order:
mcp-k6 (preferred):
get_documentation("best_practices"),get_documentation("javascript-api/k6-browser"),validate_script(...).k6 x docsCLI (always available):k6 x docs using-k6 thresholds k6 x docs javascript-api k6-http k6 x docs search "websocket migration"2-call strategy: try the direct path first; if it returns a topic list, pick the subtopic and call again. Full parent paths required (
using-k6 thresholds, notthresholds).k6 x docsserves docs for the installed k6 version -- it may lag the target version when migrating.Web fetch (last resort):
https://grafana.com/docs/k6/latest/.
Async check pattern
A common browser-test bug: using check() from k6 with async predicates. The
built-in check() does not await Promises, so
check(page, { 'title': p => p.locator('h1').textContent() === 'Foo' }) silently
passes because the Promise object is truthy. Two valid fixes:
Async-aware check from jslib:
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js'-- then predicates can beasyncandawaitinside them works.Resolve the value before the check:
const text = await page.locator('h1').textContent(); check(text, { ... })-- keeps the standard synccheckfromk6.
When you hit this during any workflow (migration, refactor, audit), flag it as a behavioral bug and propose one of these fixes.
Script sources
GCk6-hosted -- fetched and pushed via
k6-manage§5 (GET → backup → edit → validate → PUT → verify sha256).Local on disk -- read and edit directly. Validate before presenting.
Determine the source before starting: a GCk6 test URL or ID is cloud-hosted; a file path is local.
Authoring a new test, not maintaining one? This skill improves scripts that already exist. To write a new browser test from a plain-language user journey (selectors discovered by exploring the live site), use the k6-browser-test skill; for other new k6 scripts, use the k6 skill.
Workflows
Full procedures are in references/workflows.md:
Threshold tightening -- propose values with observed-metric justification, diff, apply, Class A verify.
Version migration -- find deprecated/renamed APIs, classify syntactic vs behavioral, apply, Class B verify.
Service change adaptation -- map each service change to a script change, propose fixes, Class B verify.
Refactoring -- find issues, auto-apply syntactic, propose behavioral, Class B verify after confirmation.
Best practices audit -- doc-driven audit across thresholds, load design, resource management, code quality, and browser specifics.
All five follow behavior-aware change control: auto-apply syntactic changes, present behavioral ones as diffs for confirmation.
Gotchas
| Issue | Detail |
|---|---|
| Cloud script format | GCk6 scripts can be single files or tar archives. Detect with file(1) before editing (see k6-manage §5). |
| Zero-observation thresholds | A threshold on a metric with no observations passes by default. When adding new thresholds, ensure the metric is actually emitted by the test. |
| abortOnFail cascades | If a threshold has abortOnFail: true, tightening it means runs abort earlier. Warn the user. |
| Browser script validation | Browser scripts can't be validated with k6 run --iterations 1 without a browser. Use k6 inspect for parse-only validation, or validate_script via mcp-k6. |
| k6 x docs version alignment | k6 x docs serves docs for the installed k6 version; when migrating to a newer version, local docs may not reflect the target API. Note this in migration lookups. |
| Script drift after edit | After pushing a cloud-hosted script, the next run uses the new version, but historical runs keep their bundled snapshot. To investigate a past failure, compare the run-bundled script (read-only), not the current one. |
References
references/workflows.md-- step-by-step procedures for the five maintenance tasksreferences/verification.md-- per-class post-edit verification recipes
Files
- ATTRIBUTION.mdAdded by AutoGineer877 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md9.9 KiB
- references/verification.md4.6 KiB
- references/workflows.md12.2 KiB
references/verification.md
Post-edit verification recipes
Detailed recipes for the verification matrix in SKILL.md. Classify the change
(Class A vs B) and test duration with the matrix, then follow the matching
recipe below.
Contents
Class A: historical pass/fail prediction
Class B short tests: full cloud run
Class B long tests: local + cloud smoke
Edge cases
Class A: historical pass/fail prediction
For threshold-only changes, a fresh cloud run adds no information that the existing historical data doesn't already provide. The metric values the new threshold will evaluate are the same data the old threshold has been evaluating, run after run. Verify deterministically:
Query the relevant metric aggregate across the last N completed runs using the multi-run endpoint (k6-manage references/metrics.md §8) -- use the same aggregate method as the threshold (
histogram_quantile(0.95)forp(95),ratiofor rate thresholds, etc.).For each historical value, mark pass/fail under the new threshold.
Present an impact table to the user before applying the change:
| Run | Observed p95 | < 500 (old) | < 800 (new) | |-----|--------------|-------------|-------------| | R-3 | 380ms | pass | pass | | R-2 | 520ms | fail | pass | | R-1 | 850ms | fail | fail |If the proposed value is close to the observed peak, soft-warn: "headroom is X% over observed peak -- accept that a future run with normal variance might fail." Don't gate on user acknowledgement, just make it visible.
This is more informative than running once: a fresh run is just one more sample on top of the existing N. The prediction table uses the entire historical distribution.
Class B short tests: full cloud run
Start the test via POST /load_tests/{id}/start (k6-manage §11), poll
/test_runs/{id} until status=completed, confirm result=passed. If
any thresholds failed, surface them with the same metric query you'd use
in trend analysis so the user can compare against the historical
distribution.
Class B long tests: local + cloud smoke
The POST /start endpoint accepts no runtime overrides -- running the
saved test always runs it as-defined, for its full duration. Two layers of
verification avoid burning the full test:
Local 1-iteration smoke -- catches obvious bugs (broken selectors, import errors, runtime exceptions) for free:
k6 run --vus 1 --iterations 1 script.jsFor browser tests, requires chromium locally. Skip this layer if chromium isn't installed; the cloud smoke below catches the same errors. Doesn't validate cloud-specific behaviour (load zones, distributed VUs, k6 cloud env vars, IP allowlists).
k6 cloud runwith CLI overrides on a local copy -- validates cloud-side execution without the full duration:# Authenticate first (k6-manage §9) TOKEN=$(gcx --context <ctx> k6 auth token) STACK=$(gcx --context <ctx> config view --minify -o json | jq -r '.contexts[].grafana.server') k6 cloud login --token "$TOKEN" --stack "$STACK" # Run a local copy with overrides -- doesn't touch the saved test k6 cloud run --vus 1 --iterations 1 script.jsFor scripts where VUs/iterations live inside
scenarios.*(CLI overrides don't apply to scenario-based configs), add a temporarysmokescenario at vus=1/iterations=1 to a local copy and run with--scenario smoke. PUT the unmodified original (without the smoke scenario) to the saved test after the smoke passes.
Only after both smoke layers pass do the PUT to the saved test. The next scheduled run is the final long-term confidence check, but don't gate on it -- the cloud smoke already validated cloud-side execution of the new bytes.
Edge cases
Changes to
scenarios.*.vus,duration, oriterationsare declarative but alter runtime behaviour (different load → different metric distributions). Treat as Class B even though the diff is in the options block.Loosening thresholds is Class A and uses the same prediction recipe. Show which past failing runs would have passed under the new value; this surfaces the "you're hiding existing failures" risk explicitly. Loosening is allowed only when the user asks; don't propose it.
k6 cloud runrequires a separatek6 cloud login-- gcx auth doesn't carry over (see k6-manage §9). The login token is single-stack, so switching contexts requires re-login.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs network access
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Grafana Labs
- Publisher
- Grafana Labs (Official)
- Source
- grafana/skills · skills/grafana-k6/k6-test-maintenance · commit 8fb72a5
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Grafana Labs.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download k6-test-maintenance.zip