Running a load test is only half the battle. If you cannot analyze the data, your test is practically useless. In the past, k6 developers had to export raw metrics to external databases just to see what was happening during execution. If you wanted to watch response times live, you had to spin up an entire local stack of InfluxDB and Grafana. While that remains a great pattern for long-term retention, it is way too slow for quick validations.
Fortunately, since version 0.49.0, k6 has shipped with a built-in interactive web dashboard. Let us look at how this dashboard works and how to stream raw telemetry data using NDJSON.
The Native Web Dashboard
The native k6 web dashboard leverages Server-Sent Events (SSE) to stream performance metrics in real time directly to your browser. As the test runs, the engine feeds throughput, error rates, and response time percentiles to an interactive browser interface.
You configure the dashboard using standard environment variables. This is incredibly useful for orchestrating automated runs within runner environments. Here are the core variables you need to control execution:
# Enable the dashboard and host it on a public interface
export K6_WEB_DASHBOARD=true
export K6_WEB_DASHBOARD_HOST=0.0.0.0
export K6_WEB_DASHBOARD_PORT=5665
export K6_WEB_DASHBOARD_PERIOD=10s
export K6_WEB_DASHBOARD_OPEN=false
# Export the dashboard as a compressed, self-contained HTML report
export K6_WEB_DASHBOARD_EXPORT=reports/performance_report.html.gz
For automated pipelines, setting the port to -1 disables the active HTTP server while preserving the file export functionality. This lets k6 run headless in the background, dumping a beautiful, self-contained HTML report that you can archive or share with your team.
Raw NDJSON Metrics Streaming
If you need to feed k6 metrics to custom analytical tools or parsing scripts, you can use the raw JSON output option. By passing the --out json=filepath.json flag, k6 streams every generated metric point to a Newline-Delimited JSON (NDJSON) file.
This stream consists of two distinct line types: Metric declarations and Point data. Let us analyze their structure so you can parse them easily.
1. Metric Declaration Type
This line defines the metric instrument, its target type, and any registered thresholds. It is written when k6 initializes the test session:
{
"type": "Metric",
"metric": "http_req_duration",
"data": {
"type": "trend",
"contains": "time",
"thresholds": ["p(95)<200"],
"submetrics": null
}
}
2. Metric Point Type
These lines represent individual measurement points captured during execution. Every single request, check, or iteration yields a new Point line containing raw values, timestamp coordinates, and registered tags:
{
"type": "Point",
"metric": "http_req_duration",
"data": {
"time": "2026-05-24T15:41:00.12345678Z",
"value": 142.58,
"tags": {
"group": "::executeLoadTest",
"status": "200",
"method": "POST",
"scenario": "throughput_ramp"
}
}
}
By parsing this stream, you can build custom real-time visualization engines, write automated anomaly detection scripts, or filter metrics by dynamic tags on the fly.
To learn how to store these raw metrics in time-series databases for historical trend analysis, check out k6 Observability: InfluxDB vs Prometheus Remote Write and Grafana Cloud. If you want to automatically publish these interactive HTML reports inside pipelines, read k6 in CI/CD: Automated Pipeline Orchestration in Azure DevOps and GitHub Actions. If you are executing these reporting scenarios on Windows, see our guide on k6 Workload Execution and static Gzip HTML Report Generation on Windows.