---
title: "k6 scripted check | Grafana Cloud documentation"
description: "k6 scripted checks can execute k6 tests in Grafana Synthetic Monitoring to monitor transactions and user flows with JavaScript scripts."
---

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

# k6 scripted check

k6 scripted checks can execute [k6 tests](/docs/k6/latest/) in Synthetic Monitoring. Use k6 scripted checks to monitor transactions and user flows by implementing workflows, custom logic, and validations in JavaScript.

With k6 scripted checks, you can:

- Define custom user behavior and complex request logic.
- Leverage the flexibility of a scripting language.
- Test HTTP/S and WebSocket services.
- Utilize the [k6 API](/docs/k6/latest/javascript-api/) and other JavaScript libraries.
- Enable OpenTelemetry traces for server-side correlation.
- Reuse the same k6 script for distinct testing goals.

In the Synthetics app, you create a k6 scripted check with the **Scripted** option. Its [check type identifier](/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/checks/#check-type-identifiers) is `scripted`, which the REST API, Terraform, check metrics, and the **Checks** list use. To compare it with the other check types, refer to [Choose a check type](/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/checks/#choose-a-check-type).

## How it works

A k6 check runs one iteration of a k6 test at short, frequent intervals to proactively monitor applications and services.

An [iteration](/docs/k6/latest/reference/glossary/#iteration) is one run of the script’s `default` function or the function selected by a scenario’s `exec` option. It can include multiple requests or browser interactions. Each scheduled execution from a probe runs one iteration.

Synthetic Monitoring results are stored as Prometheus metrics and Loki logs, which allow you to [set up Grafana alerts](/docs/grafana-cloud/testing/synthetic-monitoring/configure-alerts/configure-per-check-alerts/) for custom notifications and incident management.

The k6 scripts in Synthetic Monitoring are [broadly compatible](#compatibility) with other k6 products, like the k6 CLI and Grafana Cloud Performance Testing. This allows you to reuse the same k6 script for [various use cases](/docs/k6/latest/#use-cases), enhancing testing productivity and coverage.

## Get started

You can write and execute a k6 script from the code editor in the Synthetics UI.

1. On the left-side menu, select **Testing &amp; synthetics** and then **Synthetics**.
2. Click **Create new check** or **Create your first check**.
3. Choose **Scripted** as your check type.
4. Set the value for the required [options](#options).
5. Edit or copy your k6 script under **Script**.
6. Schedule or run the check.
   
   1. Click **Save** to schedule the check.
   2. Click **Test** to run the k6 script.

For development and debugging, you can write and execute the k6 script from your local machine using the k6 CLI and your IDE. After completing the k6 script, create a new scripted check or update the script of an existing one.

The Synthetics script editor includes a few scripts with basic examples. To get started implementing your first k6 scripts, refer to:

- [Running k6](/docs/k6/latest/get-started/running-k6/)
- [k6 test for functional behavior](/docs/k6/latest/examples/get-started-with-k6/test-for-functional-behavior/)

## Select a k6 version channel

On the **Script** step of the [check form](/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/checks/#the-check-form), select a channel from the **k6 version channel** list. For details, refer to [Manage k6 versions](/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/manage-k6-versions/).

## Options

The list of common options to all check types:

The frequency and timeout ranges in this table apply to k6 scripted and k6 browser checks.

Expand table

| Option          | Description                                                                                                                                                                             |
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Enabled         | Whether the check is enabled or not.                                                                                                                                                    |
| Job name        | Refer to the check name. Check metrics include a `job` label with the value of this option.                                                                                             |
| Target          | Target of the check request. Check metrics include an `instance` label with the value of this option.                                                                                   |
| Probe locations | The locations where the check should run from. Check metrics include a `probe` label with the value of the probe location running the check.                                            |
| Frequency       | The frequency the check should run in seconds. The value can range from 60 to 3600 seconds. Only the `sm_check_info` metric includes the `frequency` label.                             |
| Timeout         | Maximum execution time for the check. The value can range from 1 to 180 seconds.                                                                                                        |
| Custom labels   | (Optional) Custom labels applied to check metrics. Refer to [Custom labels](/docs/grafana-cloud/testing/synthetic-monitoring/analyze-results/custom-labels/) for querying instructions. |

Additionally, k6 scripted checks have the following options:

Expand table

| Option | Description                                                                                              |
|--------|----------------------------------------------------------------------------------------------------------|
| Script | The k6 script to execute periodically. For further details, refer to [k6 compatibility](#compatibility). |

### Supported k6 Options

[k6 options](/docs/k6/latest/using-k6/k6-options/) can be used to configure a wide range of features when running the k6 script. In Synthetic Monitoring, k6 options can only be set in the script `options` object:

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

```javascript
export const options = {
  tags: { foo: 'bar' },
  userAgent: 'MyK6UserAgentString/1.0',
};
```

Several k6 options don’t apply in the context of Synthetic Monitoring. Here is the list of supported options:

Expand table

| k6 Option                                                                                          | Description                                                                                           |
|----------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
| [`batch`](/docs/k6/latest/using-k6/k6-options/reference/#batch)                                    | Max number of simultaneous connections of a `http.batch()` call                                       |
| [`batch-per-host`](/docs/k6/latest/using-k6/k6-options/reference/#batch-per-host)                  | Max number of simultaneous connections of a `http.batch()` call for a host                            |
| [`discardResponseBodies`](/docs/k6/latest/using-k6/k6-options/reference/#discard-response-bodies)  | Specify whether response bodies should be discarded                                                   |
| [`httpDebug`](/docs/k6/latest/using-k6/k6-options/reference/#http-debug)                           | log all HTTP requests and responses                                                                   |
| [`insecureSkipTLSVerify`](/docs/k6/latest/using-k6/k6-options/reference/#insecure-skip-tls-verify) | A boolean specifying whether k6 should ignore TLS verifications for connections established from code |
| [`maxRedirects`](/docs/k6/latest/using-k6/k6-options/reference/#max-redirects)                     | The maximum number of HTTP redirects that k6 will follow                                              |
| [`noConnectionReuse`](/docs/k6/latest/using-k6/k6-options/reference/#no-connection-reuse)          | A boolean specifying whether k6 should disable keep-alive connections                                 |
| [`setupTimeout`](/docs/k6/latest/using-k6/k6-options/reference/#setup-timeout)                     | Specify how long the `setup()` function is allow to run before it’s terminated                        |
| [`systemTags`](/docs/k6/latest/using-k6/k6-options/reference/#system-tags)                         | Specify which System Tags will be in the collected metrics                                            |
| [`tags`](/docs/k6/latest/using-k6/k6-options/reference/#tags)                                      | Specify tags that should be set test-wide across all metrics                                          |
| [`teardownTimeout`](/docs/k6/latest/using-k6/k6-options/reference/#teardown-timeout)               | Specify how long the teardown() function is allowed to run before it’s terminated                     |
| [`throw`](/docs/k6/latest/using-k6/k6-options/reference/#throw)                                    | A boolean specifying whether to throw errors on failed HTTP requests                                  |
| [`tlsAuth`](/docs/k6/latest/using-k6/k6-options/reference/#tls-auth)                               | A list of TLS client certificate configuration objects                                                |
| [`tlsCipherSuites`](/docs/k6/latest/using-k6/k6-options/reference/#tls-cipher-suites)              | A list of cipher suites allowed to be used by in SSL/TLS interactions with a server                   |
| [`tlsVersion`](/docs/k6/latest/using-k6/k6-options/reference/#tls-version)                         | String or object representing the only SSL/TLS version allowed                                        |
| [`userAgent`](/docs/k6/latest/using-k6/k6-options/reference/#user-agent)                           | A string specifying the User-Agent header when sending HTTP requests                                  |

## Metrics

Synthetic checks store their results as Prometheus metrics, including the list of common metrics to all check types:

Expand table

| Metric                       | Description                                                         |
|------------------------------|---------------------------------------------------------------------|
| `probe_all_duration_seconds` | Returns how long the probe took to complete in seconds (histogram). |
| `probe_duration_seconds`     | Returns how long the probe took to complete in seconds.             |
| `probe_all_success`          | Displays whether or not the probe was a success (summary).          |
| `probe_success`              | Displays whether or not the probe was a success.                    |
| `sm_check_info`              | Provides information about a single check configuration.            |

> Note
> 
> For k6-based checks, `probe_duration_seconds` has the same value as `probe_script_duration_seconds`: the time k6 spends running the script. It does not include the time k6 needs before the script starts, which covers starting k6, downloading remote modules the script imports, for example from `jslib.k6.io`, and compiling the script. Modules are downloaded one after another, so a slow module host can make this startup take longer than the script itself.
> 
> If the startup fails, for example because a module download fails or times out, or because the script has a syntax error, the script never runs and `probe_script_duration_seconds` is not reported. In that case, `probe_duration_seconds` reports the full time the check took, up to the check timeout.

### k6 metrics

Scripted checks also collect the metrics produced by k6 and store them as Prometheus metrics.

k6 has two types of metrics:

- [Built-in metrics](/docs/k6/latest/using-k6/metrics/reference/): These are metrics collected by every k6 test, such as data received and total number of requests.
- [Custom metrics](/docs/k6/latest/using-k6/metrics/create-custom-metrics/): These are metrics that you can create in your test script to measure anything that’s specific to your system or business logic. In Prometheus, they’re renamed to `probe_K6_METRIC_NAME` and mapped to [Prometheus gauges](https://prometheus.io/docs/concepts/metric_types/#gauge).

k6 built-in metrics are transformed in Synthetic Monitoring as follows:

Expand table

| Metric                                  | Additional labels                                                              | Description                                                                                                                                                                                                                                                                                   |
|-----------------------------------------|--------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `probe_check_success_rate`              | `check`, `scenario`                                                            | The pass/fail rate of assertions (calls to [`check()`](/docs/k6/latest/javascript-api/k6/check/)). The `check` label identifies the assertion by name. The value can range between 0 (all failed) and 1 (all passed).                                                                         |
| `probe_checks_total`                    | `check`, `result`, `scenario`                                                  | The number of passing and failing assertions (calls to [`check()`](/docs/k6/latest/javascript-api/k6/check/)). The `check` label identifies the assertion by name. The `result` label can have a value of `pass` or `fail`.                                                                   |
| `probe_data_received_bytes`             | `scenario`                                                                     | The total data received for all requests made while executing the script. It corresponds to the [`data_received` metric](/docs/k6/latest/using-k6/metrics/reference/).                                                                                                                        |
| `probe_data_sent_bytes`                 | `scenario`                                                                     | The total data sent for all requests made while executing the script. It corresponds to the [`data_sent` metric](/docs/k6/latest/using-k6/metrics/reference/).                                                                                                                                |
| `probe_http_all_duration_seconds`       | `method`, `name`, `phase`, `proto`, `scenario`, `status`, `tls_version`, `url` | Histogram of HTTP request duration by phase.                                                                                                                                                                                                                                                  |
| `probe_http_duration_seconds`           | `method`, `name`, `phase`, `proto`, `scenario`, `status`, `tls_version`, `url` | Duration of HTTP request by phase, in seconds. This is the combined total of the `http_req_blocked`, `http_req_connecting`, `http_req_receiving`, `http_req_sending`, `http_req_tls_handshaking`, and `http_req_waiting` [k6 HTTP metrics](/docs/k6/latest/using-k6/metrics/reference/#http). |
| `probe_http_error_code`                 | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | The [k6 error code](/docs/k6/latest/javascript-api/error-codes/) for the HTTP request.                                                                                                                                                                                                        |
| `probe_http_got_expected_response`      | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | The `expected_response` tag set on HTTP requests by k6. By default, response statuses between 200 and 399 are true. For more details, refer to [k6 HTTP request tags](/docs/k6/latest/using-k6/http-requests/#http-request-tags).                                                             |
| `probe_http_info`                       | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | Includes additional labels associated with an HTTP request, such as HTTP version and TLS version. Always returns 1.                                                                                                                                                                           |
| `probe_http_requests_failed`            | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | Indicates whether the individual HTTP request failed.                                                                                                                                                                                                                                         |
| `probe_http_requests_failed_total`      | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | The number of failed HTTP requests while executing the script.                                                                                                                                                                                                                                |
| `probe_http_requests_total`             | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | The number of HTTP requests initiated while executing the script.                                                                                                                                                                                                                             |
| `probe_http_ssl`                        | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | Indicates whether TLS was used for the request.                                                                                                                                                                                                                                               |
| `probe_http_status_code`                | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | Response HTTP status code.                                                                                                                                                                                                                                                                    |
| `probe_http_total_all_duration_seconds` | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | Histogram of total HTTP request duration.                                                                                                                                                                                                                                                     |
| `probe_http_total_duration_seconds`     | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | Total duration of the HTTP request in seconds. It corresponds to the [`http_req_duration` metric](/docs/k6/latest/using-k6/metrics/reference/).                                                                                                                                               |
| `probe_http_version`                    | `method`, `name`, `proto`, `scenario`, `status`, `tls_version`, `url`          | Returns the HTTP version of the response.                                                                                                                                                                                                                                                     |
| `probe_iteration_all_duration_seconds`  | `scenario`                                                                     | Histogram of the k6-reported iteration duration.                                                                                                                                                                                                                                              |
| `probe_iteration_duration_seconds`      | `scenario`                                                                     | Returns the k6-reported iteration duration in seconds. It corresponds to the [`iteration_duration` metric](/docs/k6/latest/using-k6/metrics/reference/).                                                                                                                                      |
| `probe_script_all_duration_seconds`     | None                                                                           | Histogram of the k6-reported scripted-check execution time.                                                                                                                                                                                                                                   |
| `probe_script_duration_seconds`         | None                                                                           | Returns the k6-reported script execution time in seconds. Excludes k6 startup, such as downloading remote modules and compiling the script.                                                                                                                                                   |

### Visualization

You can query all the produced check metrics with `Grafana Explore`, where you can create custom panels and add them to your dashboards.

Additionally, each check includes a dashboard displaying the results of the most relevant metrics. To learn more about the various visualization options, refer to [Analyze results](/docs/grafana-cloud/testing/synthetic-monitoring/analyze-results/).

## Compatibility

Grafana Cloud Synthetic Monitoring has the following limitations for k6 scripts, compared to running them locally or using Grafana Cloud k6:

### Workload options

Each k6 check execution runs one [iteration](/docs/k6/latest/reference/glossary/#iteration): one run of the script’s `default` function or the function selected by a scenario’s `exec` option. The system ignores options such as `vus`, `duration`, `stages`, and `iterations`.

### Timeout

k6 checks have a maximum execution time. Configure this limit with the [`Timeout` option](#options) in the UI.

### k6 CLI

You can’t use the k6 CLI to run or upload k6 scripts to Grafana Cloud Synthetic Monitoring.

### Other k6 APIs

[Thresholds](/docs/k6/latest/using-k6/thresholds/) aren’t supported.

### Labels and k6 tags

[Custom labels](/docs/grafana-cloud/testing/synthetic-monitoring/analyze-results/custom-labels/) that you define in the UI are separate from the tags you define in your k6 script with the [k6 `tags` option](/docs/k6/latest/using-k6/k6-options/reference/#tags).

Where a k6 tag appears depends on where you set it:

- **Test-wide tags**, set in the `options.tags` field, appear on the metrics that k6 generates: `probe_checks_total`, `probe_check_success_rate`, `probe_data_sent_bytes`, `probe_data_received_bytes`, and `probe_iteration_duration_seconds`. They don’t appear on the metrics that the Synthetic Monitoring agent generates, such as `probe_all_duration_seconds_*`, `probe_all_success_*`, `probe_duration_seconds`, `probe_script_duration_seconds`, `probe_success`, and `sm_check_info`.
- **Request-specific tags**, set on an individual request, appear only on the corresponding HTTP request metrics: `probe_http_duration_seconds`, `probe_http_status_code`, `probe_http_info`, and `probe_http_requests_total`.

In check logs, k6 tags aren’t indexed as labels. They appear as `logfmt` key-value pairs in the log line itself, so you can filter on them with the LogQL label-filter syntax.

> Caution
> 
> Unlike custom labels, k6 tags aren’t validated against the [reserved system label names](/docs/grafana-cloud/testing/synthetic-monitoring/system-labels/), because Synthetic Monitoring doesn’t inspect the contents of your script.
> 
> If a k6 tag name collides with a reserved system label name, Synthetic Monitoring overwrites your tag value with its own value on metrics. Check logs are unaffected, because k6 tags aren’t indexed as labels there.

### Load local files

For security reasons, probes can’t load local files. k6 APIs such as [`open`](/docs/k6/latest/javascript-api/init-context/open/), [`fs`](/docs/k6/latest/javascript-api/k6-experimental/fs/), and [`grpc.load`](/docs/k6/latest/javascript-api/k6-net-grpc/client/client-load/) (non-reflection) aren’t supported.

To import local modules or libraries, use a bundler to build your k6 script with its dependencies locally, then copy the output into the script option.
