K6
Grafana LabsOfficialPublished by Grafana Labs
- Skill
- Tool integration
- Software development
- Apache-2.0
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured workflow for creating, refining, and validating k6 test scripts. It covers a wide range of testing types including load, stress, spike, soak, smoke, breakpoint, functional, and protocol testing. The agent uses provided example templates to scaffold scripts, applies best practices for performance testing, and performs automated validation by executing the generated code to ensure it meets requirements before delivery.
What it does
- Generates k6 test scripts based on specific performance or functional requirements.
- Validates scripts by executing them to ensure they are runnable and free of errors.
- Applies performance testing best practices such as thresholds, sleep intervals, and proper metric tracking.
- Provides guidance on choosing the correct k6 executor and scenario configuration.
- Reviews scripts against established quality standards for browser, HTTP, WebSocket, and gRPC tests.
- Integrates with k6 documentation to resolve API or configuration questions.
When to use it
- When you need to create a new load, stress, or functional test script for an API or service.
- When you need to debug or optimize an existing k6 test script.
- When you need to implement specific performance thresholds or custom metrics.
- When you are setting up complex test scenarios involving multiple executors or cloud execution.
Advantages
- Ensures scripts are syntactically correct and functional through automated validation.
- Promotes consistent testing patterns using verified example templates.
- Reduces manual effort in configuring complex load patterns and thresholds.
- Enforces performance testing best practices to avoid common pitfalls like missing thresholds or improper think time.
Usage examples
- “Create a load test for my API that ramps up to 50 VUs over 5 minutes.”
- The agent generates a k6 script using a ramping-vus executor, sets appropriate thresholds for latency and error rates, and validates the script by running an inspection.
- “Write a functional test for my login page using k6 browser.”
- The agent creates a browser-based test script using k6/browser, implements expect() assertions for verification, and ensures proper page cleanup in a try/finally block.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/grafana/k6/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip k6.zip -d .agents/skills
Documentation by Grafana Labs
k6 Script Generation
Efficiency note: This is a short linear recipe (read example → adapt → save → validate → review). A todo list would just mirror the headings without adding value, so skip the planning overhead and execute the steps directly.
Agent-agnostic: The steps below describe capabilities, not specific tools. Where a step says "fetch a URL" or "write a file", use whatever your agent provides for that capability (e.g. a web-fetch tool, a file-write tool, or shell
curl/tee).
Step 1: Pick the right example file
Read only the file that matches the user's request. Examples provide structural scaffolding — the correct scaffold, option shapes, and import patterns.
| User needs | Read this file |
|---|---|
| HTTP REST, auth flow, batch requests | examples/http.js |
| HTML parsing with parseHTML, SharedArray | examples/html.js |
| WebSocket | examples/websocket.js |
| gRPC | examples/grpc.js |
| Browser automation | examples/browser.js |
Browser + functional test / expect() / k6-testing | examples/functional.js (browser scenario) |
Functional/integration tests, expect(), k6-testing | examples/functional.js |
| Custom metrics, execution module, handleSummary, per-vu-iterations | examples/metrics.js |
| Load patterns, all executors (ramping, arrival rate, per-VU, etc.) | examples/executors.js |
Cloud run, --local-execution, cloud options | examples/cloud.js |
| Crypto (HMAC, MD5, SHA256) or encoding (base64) | examples/crypto-encoding.js |
| xk6-faker | examples/ext-faker.js |
| xk6-redis | examples/ext-redis.js |
| xk6-sql / sqlite3 / postgres | examples/ext-sql.js |
| xk6-exec | examples/ext-exec.js |
| xk6-dns | examples/ext-dns.js |
| xk6-tls | examples/ext-tls.js |
| xk6-tcp | examples/ext-tcp.js |
| xk6-crawler | examples/ext-crawler.js |
Example files live in the examples/ directory alongside this SKILL.md.
When the request matches multiple rows (e.g. "browser" + "functional test"), prefer the row whose assertion style fits the intent. If the user says "functional test", "assert", "verify", or "expect", use functional.js even if the test involves a browser — it demonstrates expect() with auto-retrying browser matchers. Use browser.js for browser load/performance tests that don't emphasize correctness assertions.
Browser test from a plain-language journey? If the user describes a browser flow in prose and the selectors aren't known yet — i.e. they must be discovered by driving the live site — defer to the k6-browser-test skill, which explores the live page to resolve real getBy* locators before writing the test. Use the browser rows above when the page structure and selectors are already known.
Step 2: Adapt the example
Use the loaded example as the starting point. Adapt it to the user's exact requirements:
Change endpoints, VU counts, durations, thresholds
Add or remove scenario steps
Rename functions and variables to match the domain
Every expression must be complete and runnable — no
{ ... },// TODO, or stubsMatch the request — don't over-build. Implement exactly what was asked. Don't add custom request tags, extra
sleep()calls, additional endpoints, oroptionsthe user didn't request. Unrequested complexity lowers quality and reduces adherence to the spec.
For multi-scenario scripts (browser + HTTP, cloud): use named scenarios with exec pointing to separate exported functions.
Step 3: Fill gaps with docs (only if needed)
The example covers common patterns. Adapt from it directly. Skip this step entirely if the example provides everything you need.
Only reach for docs if:
The user asks for an API or option not demonstrated in the example, or
You are not confident about the exact signature, option name, or return type
When a gap exists, first establish the docs command (one-time per session).
The k6 x docs CLI renders content only when it detects a TTY. Since agents
run non-interactively, wrap every call with script to allocate a pseudo-TTY
and pipe the ANSI-stripped content to stdout:
# Detect OS once (macOS vs Linux have different `script` flags):
if [[ "$(uname -s)" == "Darwin" ]]; then
DOCS_CMD="script -q /dev/null k6 x docs"
else
DOCS_CMD="script -qc 'k6 x docs' /dev/null"
fi
# Verify it works — should print a topic list, NOT a "browse files" guide:
$DOCS_CMD 2>/dev/null | head -5If the output still shows "k6 documentation is a directory of markdown files",
the TTY wrapper isn't working. Fall back to web docs under
https://grafana.com/docs/k6/latest/ — fetch pages with whatever web-fetch
capability your agent has (a built-in fetch tool, or curl in a shell).
If k6 x docs fails outright (command not found, provisioning or 404 errors),
read SETUP.md — it covers auto-provisioning on k6 v1.7.0+ and the manual
xk6 build for older versions.
Then look up what you need:
$DOCS_CMD <path> # e.g. javascript-api k6-http
$DOCS_CMD <path> --depth 2
$DOCS_CMD search <term>Common CLI paths and the 2-call strategy are in docs-guidance.md.
Do not use unpkg, @types/k6, or any npm type definition URLs.
Step 4: Save
Line 1 of every script must be a generated-by comment. Get the current UTC timestamp first (the file content depends on it, so this can't be parallelized with the write):
date -u +%Y-%m-%dT%H:%M:%SZThen include it as line 1:
// Generated by grafana-k6 on 2026-03-25T22:02:20.203ZSave to k6/scripts/<descriptive-name>.js. Use lowercase kebab-case filenames. If your file-write capability doesn't create parent directories automatically, mkdir -p k6/scripts first.
The script file on disk is the deliverable — always write it. Never end the task with the script shown only in chat: Steps 5–7 (validate, review, present) all require the file to exist at k6/scripts/<name>.js. If a write fails, retry it before continuing.
Step 5: Validate
Match top-down — the first matching row wins:
| Script type | Command |
|---|---|
Imports k6/browser | k6 run k6/scripts/<name>.js |
Any ramping-vus or *-arrival-rate scenario | k6 inspect k6/scripts/<name>.js — a full run would execute the entire load profile against the target |
Other named executor: blocks (short scenarios) | k6 run k6/scripts/<name>.js |
| Everything else (HTTP, WS, gRPC) | k6 run --vus 1 --iterations 1 k6/scripts/<name>.js |
What counts as passing: for functional and browser scripts, validation passes only when the exit code is 0 and the summary shows no failed checks or expect() errors — a script that completes with failing assertions is not validated. k6's error output names the exact locator or assertion that failed (and what it waited for); use it to fix the selector or logic. For load tests, exit code 0 is a pass, and a pure threshold breach under load (exit code 99) is acceptable.
If validation fails: read stderr, fix the root cause, retry up to 3 attempts. After 3 failures, present the error and ask the user how to proceed (or, when running unattended, deliver the best attempt and clearly report the unresolved error).
Step 6: Best-practices review
General checks (all scripts)
Review the script against the rules below. The checklist is authoritative — only look up docs ($DOCS_CMD best-practices or https://grafana.com/docs/k6/latest/using-k6/) if you're uncertain about a specific rule.
export const optionswith realistic VUs/duration. Default VUs/durations make the test meaningful out of the box.Define
thresholdsfor every load test. Without thresholds the run can't fail in CI even when performance regresses, which defeats the point of running a load test. At minimum includehttp_req_durationandhttp_req_failed(or the protocol equivalent). Pure functional tests — single-iterationexpect()-only scripts — can skip this.Include
sleep()in closed-model (VU-based) load tests.sleep()represents user think time; without it, VUs hammer endpoints faster than any real user would, inflating throughput and crowding out the system under test. This applies to VU-based HTTP, WebSocket, gRPC, crypto, and extension scripts. Open-model executors (constant-arrival-rate,ramping-arrival-rate) already pace iterations to a target rate, sosleep()there is usually unnecessary — it only ties up VUs without changing the offered load. Browser scripts usepage.waitForTimeout()instead; single-iteration functional tests and one-shot connectivity/demo scripts can skip it. In event-driven WebSocket scripts, put thesleep()inside theclosehandler (seeexamples/websocket.js) — sleeping in the main function body blocks the event loop before any messages arrive.Assert every response. Browser scripts: use
expect()from k6-testing — it auto-retries against locators and replaceswaitFor()+isVisible()+check()chains. If you need a metric-trackedcheck()inside an async browser function, the standardcheckfromk6works fine as long as the predicate is synchronous —awaitthe value first, then check it. Only reach for the k6-utils wrapper (https://jslib.k6.io/k6-utils/1.5.0/index.js) when the predicate itself mustawaitsomething: a bareasyncpredicate returns a Promise, which is always truthy, so the check silently passes. HTTP/gRPC/WS scripts: usecheck()for metric-tracked assertions, orexpect()for functional tests. Silent failures are worse than loud ones.Browser scripts: wrap interactions in
try/finallywithpage.close()infinally, so pages clean up even when assertions throw.gRPC scripts: wrap the iteration's calls in
try/finallyand callclient.close()in thefinallyblock, so the connection is released even when a check throws mid-iteration.WebSocket scripts: wrap
JSON.parseof incoming messages intry/catch— servers can send non-JSON frames, and one bad frame shouldn't kill the VU.No
let/varat top level — useconst, since module-scope state is shared across VUs and mutability there is almost always a bug.No deprecated imports — use
k6/websocketsfor WebSockets; bothk6/wsandk6/experimental/websocketsare deprecated.
Load & breakpoint tests
Breakpoint tests: ramp offered load, not VUs. Use an open-model executor (
ramping-arrival-rate) so the request rate is independent of how slow the system gets; a closed model (ramping-vus) throttles itself as latency rises and masks the breaking point. Pair thresholds withabortOnFail: trueand a shortdelayAbortEvalso the run stops (and reports) once an SLO is crossed.Track SLO-relevant custom metrics for reporting: per-endpoint latency (
Trend), an errorRate, and any domain counters — plus ahandleSummarythat surfaces p95/p99, throughput (req/s), and error rate. Seeexamples/executors.jsandexamples/metrics.js.Hybrid protocol + browser load tests: wrap the browser flow in
try/catchand record failures to a custom error metric instead of letting anexpect()throw — a single flaky browser iteration must not abort a long protocol load run.
Browser scripts — recommended practices
If the script imports k6/browser, read browser-best-practices.md and apply all checks. Fix issues and re-validate.
Step 7: Present results
Full script with file path
Validation output
Best-practices notes (issues found, or "all checks passed")
Suggested run command
k6 run --vus 10 --duration 30s k6/scripts/api-load-test.js
k6 run k6/scripts/browser-test.js
k6 cloud run k6/scripts/cloud-test.js
k6 cloud run --local-execution k6/scripts/hybrid-test.js
./k6-with-faker run k6/scripts/faker-test.js
K6_BROWSER_HEADLESS=true k6 run k6/scripts/browser-test.jsStep 8: Execute
If the user confirms, run the command.
Files
- ATTRIBUTION.mdAdded by AutoGineer822 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SETUP.md1.4 KiB
- SKILL.md12.7 KiB
- browser-best-practices.md6.6 KiB
- docs-guidance.md2.6 KiB
- examples/browser.jsScript3.5 KiB
- examples/cloud.jsScript2.1 KiB
- examples/crypto-encoding.jsScript2.6 KiB
- examples/executors.jsScript3.7 KiB
- examples/ext-crawler.jsScript1.1 KiB
- examples/ext-dns.jsScript1.3 KiB
- examples/ext-exec.jsScript1.0 KiB
- examples/ext-faker.jsScript1.3 KiB
- examples/ext-redis.jsScript1.8 KiB
- examples/ext-sql.jsScript2.1 KiB
- examples/ext-tcp.jsScript1.6 KiB
- examples/ext-tls.jsScript1.2 KiB
- examples/functional.jsScript3.5 KiB
- examples/grpc.jsScript2.4 KiB
- examples/html.jsScript2.1 KiB
- examples/http.jsScript3.6 KiB
- examples/metrics.jsScript3.8 KiB
- examples/websocket.jsScript1.9 KiB
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2026 Grafana Labs
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
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 Node.js
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
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 · 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.zip