---
title: "Reading k6 output | Grafana Labs"
description: "How to find and interpret the metrics that matter in k6 terminal output"
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

## What “good” looks like in the summary

- **Thresholds section** shows your gate first; every line should be green before you trust CI with the script.
- **p95 on `http_req_duration`** is stable across two runs at the same profile (small drift is normal; wild swings mean the profile or environment is not ready).
- **`http_req_failed`** stays at zero or inside your agreed budget; mystery 4xx or 5xx under steady load deserve a check or environment fix before you tighten thresholds.
- **Checks** reflect a real success condition, not only “HTTP 200.”

## Sample k6 terminal output

The block below matches the **k6 v1 end-of-test summary** layout (thresholds first, then grouped totals). Layout and labels can change between versions; for section order, `--summary-mode`, and other options, refer to [End-of-test summary](/docs/k6/latest/results-output/end-of-test/) in the k6 documentation.

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
  █ THRESHOLDS

    http_req_duration
    ✓ 'p(95)<1500' p(95)=148.21ms
    ✓ 'p(90)<2000' p(90)=146.88ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%


  █ TOTAL RESULTS

    checks_total.......................: 90      13.122179/s
    checks_succeeded...................: 100.00% 90 out of 90
    checks_failed......................: 0.00%   0 out of 90

    ✓ status is 200
    ✓ body is not empty

    CUSTOM
    custom_waiting_time................: avg=152.355556 min=120      med=141      max=684      p(90)=147.2    p(95)=148.8

    HTTP
    http_req_duration..................: avg=140.36ms   min=119.08ms med=140.96ms max=154.63ms p(90)=146.88ms p(95)=148.21ms
      { expected_response:true }.......: avg=140.36ms   min=119.08ms med=140.96ms max=154.63ms p(90)=146.88ms p(95)=148.21ms
    http_req_failed....................: 0.00%  0 out of 45
    http_reqs..........................: 45     6.56109/s

    EXECUTION
    iteration_duration.................: avg=152.38ms   min=119.37ms med=141.27ms max=684.62ms p(90)=147.11ms p(95)=148.39ms
    iterations.........................: 45     6.56109/s
    vus................................: 1      min=1       max=1
    vus_max............................: 1      min=1       max=1

    NETWORK
    data_received......................: 519 kB 76 kB/s
    data_sent..........................: 4.9 kB 718 B/s
```

## Where to look

Values in the **Example** column are taken from the sample summary above so the table stays internally consistent.

| What you need       | Where to find it                                                           | Example from sample |
|---------------------|----------------------------------------------------------------------------|---------------------|
| **Latency (p95)**   | `http_req_duration` → `p(95)`                                              | 148.21 ms           |
| **Throughput**      | `http_reqs` → numeric rate **before** `/s` on that line (here `6.56109/s`) | 6.56109/s           |
| **Error rate**      | `http_req_failed` → percentage                                             | 0.00%               |
| **Check pass rate** | `checks_succeeded` / `checks_total` (summary layout varies by version)     | 100.00% (90 of 90)  |
| **VU count**        | `vus`                                                                      | 1                   |

## Reading threshold results

When thresholds are set, each one shows a verdict:

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
  █ THRESHOLDS

    http_req_duration
    ✓ 'p(95)<1500' p(95)=148.21ms
    ✓ 'p(90)<2000' p(90)=146.88ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%
```

**✓** (check mark) means the threshold passed. **✗** (X) means the threshold was breached (exit code 99).

## What the numbers mean together

Read one run through **three lenses**. You almost never trust a single number alone.

| Lens              | Ask                                                    |
|-------------------|--------------------------------------------------------|
| **Latency (p95)** | Are responses getting slower over time?                |
| **Throughput**    | Does request rate keep up with how many VUs you added? |
| **Correctness**   | Are HTTP failures or check failures climbing?          |

**Four common stories** (heuristics for HTTP tests at steady VUs, not guarantees):

| If you see…                                                                | Often means…                                                                                                           |
|----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| **p95 steady and low**, throughput matches your ramp, **errors near zero** | The system looks **healthy at this load**.                                                                             |
| **p95 climbs** while VUs stay flat and **throughput stalls or falls**      | Work is **backing up** (responses slower, queueing, or saturation).                                                    |
| **Errors or failed checks rise** while **p95 stays low**                   | Answers are **wrong or rejected** even when they arrive fast. Reread checks and response bodies.                       |
| **Throughput drops** with **the same VU count**                            | Each request is **costing more time** somewhere (network, app, or dependencies). Pair with `http_req_duration` trends. |
