Prerequisites
- Node.js 18+ (for script editing, not required at runtime)
- A perfscale account (sign up free)
- A URL to test — we'll use
https://httpbin.org/getas a safe placeholder
Step 1 — Install k6
# macOS
brew install k6
# Linux (Debian/Ubuntu)
sudo apt-get install k6
# Docker (no install required)
docker run --rm -i grafana/k6 run - <script.js
Step 2 — Write your first script
Create smoke.js:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
vus: 10, // 10 virtual users
duration: '30s', // run for 30 seconds
};
export default function () {
const res = http.get('https://httpbin.org/get');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}
What this does
| Setting | Meaning |
|---|---|
vus: 10 | Simulate 10 concurrent users |
duration: '30s' | Keep running for 30 seconds |
check(...) | Assert conditions — failed checks appear in results |
sleep(1) | Pause 1 second between iterations (realistic pacing) |
Step 3 — Run it locally
k6 run smoke.js
You'll see live output like:
✓ status is 200
✓ response time < 500ms
checks.........................: 100.00% ✓ 290 ✗ 0
http_req_duration..............: avg=142ms p(90)=201ms p(99)=320ms
http_reqs......................: 290 9.64/s
The key metrics:
http_req_duration— latency percentiles. Watch p99, not average.http_reqs— requests per second (throughput)checks— your assertions. Anything < 100% is a failure
Step 4 — Add a threshold
Thresholds make your test fail if performance degrades:
export const options = {
vus: 10,
duration: '30s',
thresholds: {
http_req_duration: ['p(99)<500'], // 99th percentile must be < 500ms
http_req_failed: ['rate<0.01'], // error rate must be < 1%
},
};
Now k6 run smoke.js exits with code 1 if thresholds are breached — perfect for CI gating.
Step 5 — Push to perfscale
Commit your script to your repo, then add this GitHub Actions step:
- name: Run load test
uses: grafana/setup-k6-action@v1
- name: Execute smoke test
run: k6 run smoke.js
env:
K6_CLOUD_TOKEN: ${{ secrets.PERFSCALE_TOKEN }}
That's it. Every pull request now runs this test automatically.
Next steps
- Understand k6 metrics — what each built-in metric means
- Ramp-up load patterns — constant, ramping, spike, soak
- Parameterise your script — use CSV data or environment variables