Grafana k6

Use Grafana k6 to describe a workload, generate traffic, and evaluate performance criteria as code. A useful result says what traffic reached which system, whether responses were correct, and whether the declared thresholds passed under the stated conditions.

A script that sends many requests is only a starting point. The hard part is matching the traffic model to the question and recognizing when the generator, fixture, or environment invalidates the answer.

TL;DR

Quick Example

The following script targets an endpoint you control. Prepare a disposable local or approved test service at http://127.0.0.1:8080/health that returns HTTP 200 with the exact body ok. Install the k6 CLI, save this as health.js, and run k6 run health.js. It sends a deliberately small workload; do not redirect it to a third-party system.

The intended schedule is two iteration starts per second for ten seconds. Each iteration makes one request without redirects. The four preallocated workers are a teaching choice, not a capacity estimate for your application. A slow response can occupy those workers long enough that scheduled iterations are dropped.

The 500 ms percentile threshold and zero-error criteria are illustrative, not recommended service-level objectives. Change the fixture to return a wrong body and verify that the checks threshold fails; restore it, then introduce a controlled delay to exercise the latency criterion. A correct failure is part of validating the test itself.

Core Concepts

Workload model

A closed workload maintains a chosen population of virtual users performing iterations. If responses slow down, each user takes longer before starting the next iteration, which can reduce the generated arrival rate. That may match a fixed group of workers, but it can hide overload when the real system receives independently arriving work.

The constant-arrival-rate executor schedules starts independently of response duration, subject to available virtual users. Select the model from the real traffic process. Neither a fixed population nor a fixed arrival rate is inherently the more realistic choice for every system.

Iterations, requests, and virtual users

An iteration is one execution of the scenario function. It can contain several requests, conditional branches, and waits. Therefore ten iterations per second is not automatically ten requests per second.

Each active iteration needs an available virtual user. The arrival-rate allocation guide explains preallocation and dropped iterations when capacity is insufficient. If drops occur, the test did not deliver every scheduled start; report that before interpreting latency as evidence that the system handled the intended workload.

Checks and thresholds

Checks record whether a response meets a boolean condition. Failed checks alone do not make the run finish with failed status. Thresholds establish pass/fail criteria on metrics and yield a nonzero exit status when criteria fail.

This distinction prevents a common CI error: a pipeline stays green while application responses are wrong. In the example, a successful HTTP status with an incorrect body fails the correctness threshold even though the transport-level request may be counted as successful.

Design a Workload Contract

Before raising load, describe the traffic in terms another engineer can reproduce:

Label synthetic data. A fixture with one small record can verify the script, but it cannot establish capacity for a large production dataset. For write tests, plan unique identifiers and cleanup so later runs do not measure accumulated leftovers instead of the same workload.

Keep secrets out of committed scripts and retained output. Use the test environment's approved credential mechanism, and avoid logging response bodies that can contain sensitive records. Define an explicit stop condition before any consequential load exercise.

Interpret the Whole Result

Read correctness, error rate, latency distribution, completed work, and workload-delivery metrics together. A fast unauthorized response is not a fast successful transaction. A low percentile from a handful of completed requests says little about a run where most intended work never started.

For an illustrative sizing calculation, assume five iteration starts per second and two seconds of active work per iteration. The rough concurrency product is ten active iterations. That estimate ignores variation and headroom; it is a starting point for generator sizing, not a theorem that ten workers will always suffice. Tail latency and bursts can require more.

Also inspect the generator's CPU, memory, network, and limits. A saturated generator can distort the offered workload. Increasing maxVUs without understanding the bottleneck may simply move exhaustion to another component or hide a repeatability problem.

Keep latency definitions precise. k6 request timing is not automatically a browser's rendered-page experience or a user's complete business transaction time. If the question concerns frontend rendering, add an appropriate browser measurement instead of assigning that meaning to an HTTP metric.

Build CI Gates That Produce Evidence

Begin with a small, deterministic smoke scenario to catch broken scripts, credentials, fixtures, and obvious correctness regressions. Run larger performance exercises in a controlled environment where the application and generator have known resources.

Retain the script revision, application revision, k6 version, scenario options, fixture identity, environment limits, metric summary, and threshold outcome. Keep the process exit status visible to CI. A shell wrapper that ignores a failing exit code defeats the gate even when the test itself is correct.

Choose thresholds from a product requirement or a measured baseline with a stated method. Do not tighten a number because it looks impressive, or loosen it until an unexplained regression disappears. Short runs and low counts make percentiles noisy; distinguish a smoke gate from a capacity study.

When a gate fails, first identify whether the system violated the target or the experiment failed to apply its workload. Both deserve action, but they imply different fixes. Re-run only after explaining a transient condition or changing something relevant; repeated execution is not a substitute for diagnosis.

Best Practices

Prove the script can fail

Use a controlled wrong response and verify the expected threshold fails. This checks that a green run represents the application contract rather than merely completed network activity.

Preserve pacing semantics

Arrival-rate executors already pace iteration starts. The executor documentation advises against adding an unnecessary sleep at the end of each iteration. Think separately about real pauses inside a multi-step journey.

Segment meaningful operations

Use stable names or tags for operation classes and examine the important paths separately. An aggregate percentile can conceal a slow critical endpoint behind many cheap health checks. Avoid unique per-request labels that make the output difficult to manage.

Common Mistakes

Bad: Call a passing check a CI performance gate without defining thresholds.

Correct: Establish explicit metric criteria and verify the resulting failure status reaches the pipeline.

Bad: Report the configured arrival rate as achieved throughput despite dropped iterations.

Correct: Report offered, started, and completed work with drops and errors; investigate generator capacity and system latency.

Bad: Publish a universal capacity claim from the ten-second health example.

Correct: Use it to validate the fixture and script, then build a representative workload with sufficient observation time and controlled resources.

FAQ

What is k6 in Grafana?

k6 is a performance-testing tool with code-defined scenarios and metrics. Grafana dashboards and hosted testing services can participate in a broader workflow, but the local script still needs a meaningful workload and acceptance criteria.

Is the script ordinary Node.js code?

The example uses JavaScript syntax with k6-specific modules and execution behavior. Running it with Node does not execute a k6 load test. Verify runtime and library compatibility before reusing application packages.

Does an arrival-rate executor guarantee every iteration starts?

No. Enough virtual users and generator resources must be available. Dropped iterations are evidence that scheduled work could not be started, so include that metric in both validation and reporting.

Should every CI job run a large load test?

Usually start with a bounded smoke scenario and schedule heavier exercises where resources and fixtures can be controlled. The appropriate frequency depends on cost, risk, runtime, and how quickly the result can be diagnosed.

Related Topics

References