---
title: "Advanced Examples | Grafana k6 documentation"
description: "Advanced Examples using the k6 Scenario API - Using multiple scenarios, different environment variables and tags per scenario."
---

# Advanced Examples

You can use multiple scenarios in one script, and these scenarios can be run in sequence or in parallel. Some ways that you can combine scenarios include the following:

- Have different start times to sequence workloads
- Add per-scenario tags and environment variables
- Make scenario-specific thresholds.
- Use multiple scenarios to run different test logic, so that VUs don’t run only the [`default` function](/docs/k6/latest/using-k6/test-lifecycle/).

## Combine scenarios

With the `startTime` property, you can configure your script to start some scenarios later than others. To sequence your scenarios, you can combine `startTime` with the duration options specific to the executor. (this is easiest to do with executors with set durations, like the arrival-rate executors).

This script has two scenarios, `contacts` and `news`, which run in sequence:

1. At the beginning of the test, k6 starts the `contacts` scenario. 5 VUs try to run as many iterations as possible for 5 seconds.
2. After 10 seconds, k6 starts the `news` scenario. 5 VUs each try to run 10 iterations in 20 seconds.

Along with `startTime`, `duration`, and `maxDuration`, note the different test logic for each scenario.

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

```javascript
import http from 'k6/http';

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: 'constant-vus',
      exec: 'contacts',
      vus: 5,
      duration: '5s',
    },
    news: {
      executor: 'per-vu-iterations',
      exec: 'news',
      vus: 5,
      iterations: 10,
      startTime: '10s',
      maxDuration: '20s',
    },
  },
};

export function contacts() {
  http.get('https://test.k6.io/contacts.php', {
    tags: { my_custom_tag: 'contacts' },
  });
}

export function news() {
  http.get('https://test.k6.io/news.php', { tags: { my_custom_tag: 'news' } });
}
```

## Use different environment variables and tags per scenario.

The previous example sets tags on individual HTTP request metrics. But, you can also set tags per scenario, which applies them to other [taggable](/docs/k6/latest/using-k6/tags-and-groups/#tags) objects as well.

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

```javascript
import http from 'k6/http';
import { fail } from 'k6';

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: 'constant-vus',
      exec: 'contacts',
      vus: 50,
      duration: '30s',
      tags: { my_custom_tag: 'contacts' },
      env: { MYVAR: 'contacts' },
    },
    news: {
      executor: 'per-vu-iterations',
      exec: 'news',
      vus: 50,
      iterations: 100,
      startTime: '30s',
      maxDuration: '1m',
      tags: { my_custom_tag: 'news' },
      env: { MYVAR: 'news' },
    },
  },
};

export function contacts() {
  if (__ENV.MYVAR != 'contacts') fail();
  http.get('https://test.k6.io/contacts.php');
}

export function news() {
  if (__ENV.MYVAR != 'news') fail();
  http.get('https://test.k6.io/news.php');
}
```

> Note
> 
> By default, k6 applies a `scenario` tag to all metrics in each scenario, whose value is the scenario name. You can combine these tags with thresholds, or use them to simplify results filtering.
> 
> To disable scenario tags, use the [`--system-tags` option](/docs/k6/latest/using-k6/k6-options/#system-tags).

## Run multiple scenario functions, with different thresholds

You can also set different thresholds for different scenario functions. To do this:

1. Set scenario-specific tags
2. Set thresholds for these tags.

This test has 3 scenarios, each with different `exec` functions, tags and environment variables, and thresholds:

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

```javascript
import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  scenarios: {
    my_web_test: {
      // some arbitrary scenario name
      executor: 'constant-vus',
      vus: 50,
      duration: '5m',
      gracefulStop: '0s', // do not wait for iterations to finish in the end
      tags: { test_type: 'website' }, // extra tags for the metrics generated by this scenario
      exec: 'webtest', // the function this scenario will execute
    },
    my_api_test_1: {
      executor: 'constant-arrival-rate',
      rate: 90,
      timeUnit: '1m', // 90 iterations per minute, i.e. 1.5 RPS
      duration: '5m',
      preAllocatedVUs: 10, // the size of the VU (i.e. worker) pool for this scenario
      tags: { test_type: 'api' }, // different extra metric tags for this scenario
      env: { MY_CROC_ID: '1' }, // and we can specify extra environment variables as well!
      exec: 'apitest', // this scenario is executing different code than the one above!
    },
    my_api_test_2: {
      executor: 'ramping-arrival-rate',
      startTime: '30s', // the ramping API test starts a little later
      startRate: 50,
      timeUnit: '1s', // we start at 50 iterations per second
      stages: [
        { target: 200, duration: '30s' }, // go from 50 to 200 iters/s in the first 30 seconds
        { target: 200, duration: '3m30s' }, // hold at 200 iters/s for 3.5 minutes
        { target: 0, duration: '30s' }, // ramp down back to 0 iters/s over the last 30 second
      ],
      preAllocatedVUs: 50, // how large the initial pool of VUs would be
      maxVUs: 100, // if the preAllocatedVUs are not enough, we can initialize more
      tags: { test_type: 'api' }, // different extra metric tags for this scenario
      env: { MY_CROC_ID: '2' }, // same function, different environment variables
      exec: 'apitest', // same function as the scenario above, but with different env vars
    },
  },
  discardResponseBodies: true,
  thresholds: {
    // we can set different thresholds for the different scenarios because
    // of the extra metric tags we set!
    'http_req_duration{test_type:api}': ['p(95)<250', 'p(99)<350'],
    'http_req_duration{test_type:website}': ['p(99)<500'],
    // we can reference the scenario names as well
    'http_req_duration{scenario:my_api_test_2}': ['p(99)<300'],
  },
};

export function webtest() {
  http.get('https://test.k6.io/contacts.php');
  sleep(Math.random() * 2);
}

export function apitest() {
  http.get(`https://quickpizza.grafana.com/api/json?crocId=${__ENV.MY_CROC_ID}`);
  // no need for sleep() here, the iteration pacing will be controlled by the
  // arrival-rate executors above!
}
```

## Run specific scenario via environment variable

k6 runs all [scenarios](/docs/k6/latest/using-k6/scenarios/#scenarios) listed in a test script by default. But, with some small code changes and using [environment variables](/docs/k6/latest/using-k6/environment-variables/#environment-variables), you can tell k6 to only run a specific scenario via the command-line.

The following example shows a test script that uses a `SCENARIO` environment variable, if it exists, to choose which scenario to execute:

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

```javascript
import http from 'k6/http';

const scenarios = {
  my_web_test: {
    executor: 'per-vu-iterations',
    vus: 1,
    iterations: 1,
    maxDuration: '30s',
  },
  my_api_test: {
    executor: 'per-vu-iterations',
    vus: 1,
    iterations: 1,
    maxDuration: '30s',
  },
};

const { SCENARIO } = __ENV;
export const options = {
  // if a scenario is passed via a CLI env variable, then run that scenario. Otherwise, run
  // using the pre-configured scenarios above.
  scenarios: SCENARIO ? { [SCENARIO]: scenarios[SCENARIO] } : scenarios,
  discardResponseBodies: true,
  thresholds: {
    http_req_duration: ['p(95)<250', 'p(99)<350'],
  },
};

export default function () {
  const response = http.get('https://quickpizza.grafana.com');
}
```

Then from the command line, you could run the test script and only execute the `my_web_test` scenario by running:

Bash windows powershell

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

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

```bash
SCENARIO=my_web_test k6 run script.js
```

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

```windows
set "SCENARIO=my_web_test" && k6 run script.js
```

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

```powershell
$env:SCENARIO="my_web_test"; k6 run script.js
```
