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://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
SKILL.md
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
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 or Grafana Labs.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download k6-test-maintenance.zip