/synthetic-monitoring-checks
Author Grafana Cloud Synthetic Monitoring checks, with deep coverage of k6 scripted and browser checks: SM's single-VU/single-iteration execution model, assertions that actually fail probe_success (expect() and fail() vs bare check()), secrets, deterministic scripts, robust
$ npx -y skills add grafana/skills --skill synthetic-monitoring-checks --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/synthetic-monitoring-checks
Context preview
The summary Claude sees to decide when to auto-load this skill.
Author Grafana Cloud Synthetic Monitoring checks, with deep coverage of k6 scripted and browser checks: SM's single-VU/single-iteration execution model, assertions that actually fail probe_success (expect() and fail() vs bare check()), secrets, deterministic scripts, robust
SKILL.md
synthetic-monitoring-checks.SKILL.mdname: synthetic-monitoring-checks
license: Apache-2.0
description: >
Author Grafana Cloud Synthetic Monitoring checks, with deep coverage of k6 scripted and
browser checks: SM's single-VU/single-iteration execution model, assertions that actually
fail probe_success (expect() and fail() vs bare check()), secrets, deterministic scripts,
robust browser locators, local validation with k6 run, deployment via UI/API/Terraform,
verifying probe_success, and rollback. Also helps choose the simplest sufficient check
type (HTTP/ping/DNS/TCP, MultiHTTP, scripted, browser). Use when writing a synthetic
check, monitoring a login/checkout/signup flow in production, converting a k6 script or
an OpenAPI spec into a check, authoring a browser check, validating a user journey, or
asking "is my site up from multiple regions". NOT for load, stress, or performance testing — SM runs one
iteration per execution; for load tests use the grafana-k6 plugin or Grafana Cloud k6.
For the broad Grafana Cloud Testing overview (SM + k6 Cloud + Faro), use the testing skill.
Synthetic Monitoring Check Authoring
> **Docs**: https://grafana.com/docs/grafana-cloud/testing/synthetic-monitoring/ > Broad Grafana Cloud Testing entry point (SM + k6 Cloud + Faro): [`testing`](../testing/SKILL.md) skill.
Reliability monitoring, not load testing
Synthetic Monitoring (SM) runs k6 as a **reliability/availability engine**: every check execution runs **one iteration with one VU** from each selected probe location on a fixed schedule. Success means "the user journey works right now, from this region" — detect outages before your customers do.
Do **not** apply load-testing idioms. There are no VUs to ramp, no `stages`, no load profiles, no soak/stress/spike phases, and no `thresholds` over aggregated traffic. Vocabulary: *check*, *probe*, *execution*, *uptime*, *reachability*, *user journey validation* — never "load test", "ramping", or "VUs".
**If the user actually wants load or performance testing** (throughput, latency under load, breakpoints), stop: that is Grafana Cloud k6 / the `grafana-k6` plugin's `k6` skill, not Synthetic Monitoring. A script can be shared between both products, but the goals, options, and pricing are different.
Execution model and constraints (verify against these before writing)
| Constraint | Value | |---|---| | Workload | One iteration per probe execution. Scripted and MultiHTTP run with forced `--vus 1 --iterations 1`; browser checks rely on the script's required single scenario. Either way `vus`, `duration`, `stages`, `iterations` are **ignored** — never write a load shape | | `thresholds` | **Not supported** | | Frequency | k6-class checks (scripted, MultiHTTP, browser): 60–3600s. Protocol checks (HTTP/ping/DNS/TCP/gRPC): 1–3600s. Traceroute: 120–3600s | | Timeout | Must be ≤ frequency. k6-class checks: 1–180s. Protocol checks: 1–60s. Traceroute: fixed 30s | | k6 version | Checks run on a [k6 version channel](https://grafana.com/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/manage-k6-versions/) (new checks default to the latest stable channel; `v1.x` is deprecated as of July 2026). Pin per check via the UI dropdown or `channels` in API/Terraform | | Local files | `open()`, `fs`, `grpc.load()` unsupported. Bundle local modules into the script; remote `https://jslib.k6.io/...` imports work | | HTTP request errors | SM runs k6 with `--throw`: network-level request failures throw an exception and fail the execution | | Script options SM honors | SM sets its own CLI flags, which take precedence over the script's `options` object; the options that still take effect include `batch`, `batch-per-host`, `discardResponseBodies`, `httpDebug`, `insecureSkipTLSVerify`, `maxRedirects`, `noConnectionReuse`, `setupTimeout`, `systemTags`, `tags`, `teardownTimeout`, `throw`, `tlsAuth`, `tlsCipherSuites`, `tlsVersion`, `userAgent` | | Browser memory | [1GB RAM per browser on public probes](https://grafana.com/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/checks/k6-browser/#public-probe-memory) — huge pages fail with `Target has crashed` | | Browser script format | The UI rejects bundled/minified browser scripts (import validation) — deploy those via API or Terraform |
How an execution fails (this is what agents get wrong)
`probe_success` (1/0) is the uptime signal. An execution is marked **failed** when the script throws an uncaught exception, calls `fail()`, a k6-testing `expect()` assertion fails (it calls k6's `test.abort()` under the hood), an HTTP request errors at the network level (SM's `--throw`), or the timeout is hit.
A **bare failed `check()` does NOT fail the execution** — it only records the `probe_checks_total` / `probe_check_success_rate` metrics. Checks don't affect k6's exit status without thresholds, and thresholds are disabled in SM.
Assertion patterns, in order of preference:
import { expect } from 'https://jslib.k6.io/k6-testing/0.6.1/index.js';
import { check, fail } from 'k6';
// 1. PREFERRED — assertions module. Throws on failure => execution fails,
// with a descriptive error in the check logs.
expect(res.status, 'login should succeed').toEqual(200);
expect(res.json('token')).toBeDefined();
// 2. Soft assertions — run all of them, still fail the execution at the end.
expect.soft(res.headers['Content-Type']).toContain('application/json');
// 3. check() when you also want per-assertion metrics — but pair it with
// fail() or the failure won't affect probe_success/uptime:
check(res, { 'status 200': (r) => r.status === 200 }) ||
fail(`login failed with status ${res.status}`);Name every assertion (the message argument / check name): the name is what you see in check logs and in the `check` label of `probe_checks_total` when diagnosing a failure at 3am.
Choose the simplest sufficient check type first
Cheaper for the customer, easier to maintain. Work down this list and stop at the first m
Read more
name: synthetic-monitoring-checks license: Apache-2.0 description: > Author Grafana Cloud Synthetic Monitoring checks, with deep coverage of k6 scripted and browser checks: SM's single-VU/single-iteration execution model, assertions that actually fail probe_success (expect() and fail() vs bare check()), secrets, deterministic scripts, robust browser locators, local validation with k6 run, deployment via UI/API/Terraform, verifying probe_success, and rollback. Also helps choose the simplest sufficient check type (HTTP/ping/DNS/TCP, MultiHTTP, scripted, browser). Use when writing a synthetic check, monitoring a login/checkout/signup flow in production, converting a k6 script or an OpenAPI spec into a check, authoring a browser check, validating a user journey, or asking "is my site up from multiple regions". NOT for load, stress, or performance testing — SM runs one iteration per execution; for load tests use the grafana-k6 plugin or Grafana Cloud k6. For the broad Grafana Cloud Testing overview (SM + k6 Cloud + Faro), use the testing skill.
Synthetic Monitoring Check Authoring
> **Docs**: https://grafana.com/docs/grafana-cloud/testing/synthetic-monitoring/ > Broad Grafana Cloud Testing entry point (SM + k6 Cloud + Faro): [`testing`](../testing/SKILL.md) skill.
Reliability monitoring, not load testing
Synthetic Monitoring (SM) runs k6 as a **reliability/availability engine**: every check execution runs **one iteration with one VU** from each selected probe location on a fixed schedule. Success means "the user journey works right now, from this region" — detect outages before your customers do.
Do **not** apply load-testing idioms. There are no VUs to ramp, no `stages`, no load profiles, no soak/stress/spike phases, and no `thresholds` over aggregated traffic. Vocabulary: *check*, *probe*, *execution*, *uptime*, *reachability*, *user journey validation* — never "load test", "ramping", or "VUs".
**If the user actually wants load or performance testing** (throughput, latency under load, breakpoints), stop: that is Grafana Cloud k6 / the `grafana-k6` plugin's `k6` skill, not Synthetic Monitoring. A script can be shared between both products, but the goals, options, and pricing are different.
Execution model and constraints (verify against these before writing)
| Constraint | Value | |---|---| | Workload | One iteration per probe execution. Scripted and MultiHTTP run with forced `--vus 1 --iterations 1`; browser checks rely on the script's required single scenario. Either way `vus`, `duration`, `stages`, `iterations` are **ignored** — never write a load shape | | `thresholds` | **Not supported** | | Frequency | k6-class checks (scripted, MultiHTTP, browser): 60–3600s. Protocol checks (HTTP/ping/DNS/TCP/gRPC): 1–3600s. Traceroute: 120–3600s | | Timeout | Must be ≤ frequency. k6-class checks: 1–180s. Protocol checks: 1–60s. Traceroute: fixed 30s | | k6 version | Checks run on a [k6 version channel](https://grafana.com/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/manage-k6-versions/) (new checks default to the latest stable channel; `v1.x` is deprecated as of July 2026). Pin per check via the UI dropdown or `channels` in API/Terraform | | Local files | `open()`, `fs`, `grpc.load()` unsupported. Bundle local modules into the script; remote `https://jslib.k6.io/...` imports work | | HTTP request errors | SM runs k6 with `--throw`: network-level request failures throw an exception and fail the execution | | Script options SM honors | SM sets its own CLI flags, which take precedence over the script's `options` object; the options that still take effect include `batch`, `batch-per-host`, `discardResponseBodies`, `httpDebug`, `insecureSkipTLSVerify`, `maxRedirects`, `noConnectionReuse`, `setupTimeout`, `systemTags`, `tags`, `teardownTimeout`, `throw`, `tlsAuth`, `tlsCipherSuites`, `tlsVersion`, `userAgent` | | Browser memory | [1GB RAM per browser on public probes](https://grafana.com/docs/grafana-cloud/testing/synthetic-monitoring/create-checks/checks/k6-browser/#public-probe-memory) — huge pages fail with `Target has crashed` | | Browser script format | The UI rejects bundled/minified browser scripts (import validation) — deploy those via API or Terraform |
How an execution fails (this is what agents get wrong)
`probe_success` (1/0) is the uptime signal. An execution is marked **failed** when the script throws an uncaught exception, calls `fail()`, a k6-testing `expect()` assertion fails (it calls k6's `test.abort()` under the hood), an HTTP request errors at the network level (SM's `--throw`), or the timeout is hit.
A **bare failed `check()` does NOT fail the execution** — it only records the `probe_checks_total` / `probe_check_success_rate` metrics. Checks don't affect k6's exit status without thresholds, and thresholds are disabled in SM.
Assertion patterns, in order of preference:
import { expect } from 'https://jslib.k6.io/k6-testing/0.6.1/index.js';
import { check, fail } from 'k6';
// 1. PREFERRED — assertions module. Throws on failure => execution fails,
// with a descriptive error in the check logs.
expect(res.status, 'login should succeed').toEqual(200);
expect(res.json('token')).toBeDefined();
// 2. Soft assertions — run all of them, still fail the execution at the end.
expect.soft(res.headers['Content-Type']).toContain('application/json');
// 3. check() when you also want per-assertion metrics — but pair it with
// fail() or the failure won't affect probe_success/uptime:
check(res, { 'status 200': (r) => r.status === 200 }) ||
fail(`login failed with status ${res.status}`);Name every assertion (the message argument / check name): the name is what you see in check logs and in the `check` label of `probe_checks_total` when diagnosing a failure at 3am.
Choose the simplest sufficient check type first
Cheaper for the customer, easier to maintain. Work down this list and stop at the first m
Public skills for working with Grafana, Prometheus, Loki, Tempo, Pyroscope, k6, and the broader LGTM observability stack. Compatible with Claude Code, Cursor, Codex, and any tool supporting the Agent Skills open standard.
Repo: grafana/skills
Other skills on grafana-skills.
- /admission-control
Use when the user asks to "write a validator", "add validation", "implement admission control", "write a mutating webhook", "add a mutation handler", "validate incoming resources", "implement admission logic", "add admission webhooks", "write ingress validation", or asks how to
Open skill - /app-sdk-concepts
Use when starting any grafana-app-sdk work — scaffolding a Grafana app, initializing a Grafana App Platform app, picking a deployment mode (standalone operator / grafana/apps / frontend-only), wiring app-specific config, or onboarding to the SDK. Covers `grafana-app-sdk` CLI
Open skill - /cue-kind-definition
Author CUE kind definitions for grafana-app-sdk apps - schemas, versioning, field constraints, named type definitions, custom routes, and codegen configuration. Scaffolds kinds via `grafana-app-sdk project kind add`, writes spec/status schemas with type constraints (regex, enum,
Open skill - /reconciler-logic
Implement reconcilers and watchers for grafana-app-sdk apps — write `TypedReconciler[*MyKind]` reconcile functions, apply generation-based skip patterns, do conflict-safe status updates via `resource.UpdateObject`, configure `BasicReconcileOptions` (namespace, label/field
Open skill - /adaptive-metrics
Cut Grafana Cloud Metrics cost by shrinking active-series count with Adaptive Metrics aggregation rules — auto-recommendations from query history, custom exact/regex rules, label-drop config, unused-metric detection, and Alloy remote_write fallback. Use when investigating a high
Open skill - /admin
Manage Grafana Cloud accounts — organizations, stacks, RBAC roles and assignments, SSO/SAML/OAuth/GitHub auth, service accounts for CI/CD, user invites, team membership, and API-driven provisioning. Creates stacks via the Cloud API, mints service-account tokens, applies role
Open skill

