> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/grafana/k6/llms.txt
> Use this file to discover all available pages before exploring further.

# Test Options

> Configuring k6 test execution with options

# Test Options

Options control how k6 executes your test, including the number of VUs, test duration, thresholds, and more. Options can be set in multiple ways with a clear precedence order.

## Setting Options

Options can be defined in three ways (in order of precedence):

1. **Command-line flags** - Highest priority
2. **Environment variables**
3. **Script options** - Lowest priority

<CodeGroup>
  ```javascript Script Options theme={null}
  export let options = {
    vus: 10,
    duration: '30s',
    thresholds: {
      http_req_duration: ['p(95)<500'],
    },
  };

  export default function() {
    // Test logic
  }
  ```

  ```bash Command Line theme={null}
  k6 run --vus 10 --duration 30s script.js
  ```

  ```bash Environment Variables theme={null}
  export K6_VUS=10
  export K6_DURATION=30s
  k6 run script.js
  ```
</CodeGroup>

## Basic Execution Options

### Virtual Users and Duration

The simplest way to configure a test:

```javascript theme={null}
export let options = {
  vus: 10,              // Number of virtual users
  duration: '30s',      // Test duration
};
```

### Iterations

Run a specific number of iterations instead of time-based:

```javascript theme={null}
export let options = {
  vus: 10,
  iterations: 100,      // Total iterations shared across all VUs
};
```

<Note>
  With 10 VUs and 100 iterations, each VU will execute approximately 10 iterations.
</Note>

### Stages (Ramping)

Gradually ramp VUs up and down:

```javascript theme={null}
export let options = {
  stages: [
    { duration: '10s', target: 5 },   // Ramp up to 5 VUs
    { duration: '5s', target: 5 },    // Stay at 5 VUs
    { duration: '5s', target: 0 },    // Ramp down to 0 VUs
  ],
};

export default function() {
  let res = http.get('http://httpbin.org/');
  check(res, { 'status is 200': (r) => r.status === 200 });
}
```

This creates an up-flat-down ramping profile:

```
VUs
 5│     ┌─────┐
 4│    /       \
 3│   /         \
 2│  /           \
 1│ /             \
 0└──────────────────
  0s  10s  15s  20s
```

## Thresholds

Thresholds define pass/fail criteria for your test. If a threshold fails, k6 exits with a non-zero status code.

```javascript theme={null}
import http from 'k6/http';
import { check } from 'k6';

export let options = {
  thresholds: {
    // 95th percentile response time < 500ms
    http_req_duration: ['p(95)<500'],
    
    // Max response time < 1s
    'http_req_duration{name:http://httpbin.org/post}': ['max<1000'],
    
    // 99% of requests successful
    http_req_failed: ['rate<0.01'],
    
    // 90% of checks pass
    checks: ['rate>0.9'],
    
    // Multiple conditions (all must pass)
    http_req_duration: [
      'p(95)<500',
      'p(99)<1000',
      'avg<300',
    ],
  },
};

export default function() {
  http.get('http://httpbin.org/');
  http.post('http://httpbin.org/post', {data: 'some data'});
}
```

### Threshold Expressions

Common threshold expressions:

| Expression   | Description              |
| ------------ | ------------------------ |
| `p(95)<500`  | 95th percentile \< 500ms |
| `avg<200`    | Average \< 200ms         |
| `min>100`    | Minimum > 100ms          |
| `max<1000`   | Maximum \< 1000ms        |
| `med<250`    | Median \< 250ms          |
| `rate>0.9`   | Success rate > 90%       |
| `count>1000` | Total count > 1000       |

<Warning>
  Thresholds cause the test to fail when exceeded, unlike checks which only record pass/fail without affecting the test outcome.
</Warning>

## HTTP Options

### Request Limits

```javascript theme={null}
export let options = {
  rps: 100,                    // Limit to 100 requests per second
  maxRedirects: 5,             // Follow up to 5 redirects
  batch: 10,                   // Max parallel requests in batch()
  batchPerHost: 5,             // Max parallel requests per host
};
```

### TLS/SSL Configuration

```javascript theme={null}
export let options = {
  insecureSkipTLSVerify: true,           // Skip TLS verification
  tlsVersion: {
    min: 'tls1.2',
    max: 'tls1.3',
  },
  tlsCipherSuites: [
    'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
    'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
  ],
};
```

### User Agent and Headers

```javascript theme={null}
export let options = {
  userAgent: 'k6-load-test/1.0',
  noConnectionReuse: false,              // Reuse connections
  noVUConnectionReuse: false,            // Reuse connections across iterations
};
```

## Timeouts

```javascript theme={null}
export let options = {
  setupTimeout: '60s',           // Timeout for setup() function
  teardownTimeout: '60s',        // Timeout for teardown() function
  
  noSetup: false,                // Skip setup() function
  noTeardown: false,             // Skip teardown() function
};
```

## Tags

Apply tags to all metrics in the test:

```javascript theme={null}
export let options = {
  tags: {
    environment: 'staging',
    team: 'backend',
    version: 'v1.2.3',
  },
};
```

## System Tags

Control which system tags are included with metrics:

```javascript theme={null}
export let options = {
  systemTags: [
    'status',
    'method', 
    'url',
    'name',
    'group',
    'check',
    'error',
    'error_code',
    'tls_version',
    'scenario',
    'service',
  ],
};
```

## DNS Configuration

```javascript theme={null}
export let options = {
  dns: {
    ttl: '5m',                   // DNS cache TTL
    select: 'random',            // IP selection: 'first', 'random', 'roundRobin'
    policy: 'preferIPv4',        // 'preferIPv4', 'preferIPv6', 'onlyIPv4', 'onlyIPv6', 'any'
  },
};
```

## Hosts Override

Map hostnames to IPs:

```javascript theme={null}
export let options = {
  hosts: {
    'quickpizza.grafana.com': '1.2.3.4',
    'api.example.com': '5.6.7.8',
  },
};
```

## Blocked Hostnames

Prevent requests to specific hosts:

```javascript theme={null}
export let options = {
  blockHostnames: [
    '*.google-analytics.com',
    'analytics.example.com',
  ],
};
```

## Blacklist IPs

Block requests to specific IP ranges:

```javascript theme={null}
export let options = {
  blacklistIPs: [
    '10.0.0.0/8',
    '192.168.0.0/16',
  ],
};
```

## Discard Response Bodies

Save memory by discarding response bodies:

```javascript theme={null}
export let options = {
  discardResponseBodies: true,   // Don't save response bodies
};

export default function() {
  let res = http.get('https://quickpizza.grafana.com');
  // res.body will be null when discardResponseBodies is true
  
  // Override per-request
  res = http.get('https://quickpizza.grafana.com', { 
    responseType: 'text'  // Force saving this response
  });
}
```

## Summary Configuration

```javascript theme={null}
export let options = {
  summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(90)', 'p(95)', 'p(99)'],
  summaryTimeUnit: 'ms',         // Time unit for summary: 's', 'ms', 'us'
};
```

## Paused Mode

Start test in paused state:

```javascript theme={null}
export let options = {
  paused: true,      // Start paused, resume with API or UI
};
```

## Minimum Iteration Duration

Enforce a minimum time per iteration:

```javascript theme={null}
export let options = {
  minIterationDuration: '10s',   // Each iteration takes at least 10s
};
```

## Cookie Behavior

```javascript theme={null}
export let options = {
  noCookiesReset: true,          // Don't reset cookies between iterations
};
```

## Complete Example

Here's a comprehensive example combining multiple options:

```javascript theme={null}
import http from 'k6/http';
import { check, sleep } from 'k6';

export let options = {
  // Execution
  stages: [
    { duration: '30s', target: 20 },
    { duration: '1m', target: 20 },
    { duration: '30s', target: 0 },
  ],
  
  // Thresholds
  thresholds: {
    http_req_duration: ['p(95)<500', 'p(99)<1000'],
    http_req_failed: ['rate<0.01'],
    checks: ['rate>0.95'],
  },
  
  // HTTP
  userAgent: 'k6-load-test/1.0',
  maxRedirects: 5,
  insecureSkipTLSVerify: true,
  batch: 10,
  batchPerHost: 5,
  
  // Tags
  tags: {
    environment: 'production',
    team: 'platform',
  },
  
  // Timeouts
  setupTimeout: '60s',
  teardownTimeout: '60s',
  
  // Summary
  summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(90)', 'p(95)', 'p(99)'],
};

export function setup() {
  // Setup code
  return { timestamp: Date.now() };
}

export default function(data) {
  let res = http.get('https://quickpizza.grafana.com');
  
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
  });
  
  sleep(1);
}

export function teardown(data) {
  console.log(`Test ran for ${Date.now() - data.timestamp}ms`);
}
```

## Options Reference Table

| Option                  | Type    | Default | Description                           |
| ----------------------- | ------- | ------- | ------------------------------------- |
| `vus`                   | integer | 1       | Number of virtual users               |
| `duration`              | string  | -       | Test duration (e.g., '30s', '5m')     |
| `iterations`            | integer | -       | Total iterations to execute           |
| `stages`                | array   | -       | Ramping configuration                 |
| `scenarios`             | object  | -       | Advanced execution scenarios          |
| `paused`                | boolean | false   | Start test in paused state            |
| `setupTimeout`          | string  | 10s     | Setup function timeout                |
| `teardownTimeout`       | string  | 10s     | Teardown function timeout             |
| `rps`                   | integer | 0       | Max requests per second (0=unlimited) |
| `maxRedirects`          | integer | 10      | Max HTTP redirects to follow          |
| `userAgent`             | string  | k6/...  | User-Agent header                     |
| `batch`                 | integer | 20      | Max parallel batch requests           |
| `batchPerHost`          | integer | 6       | Max parallel requests per host        |
| `insecureSkipTLSVerify` | boolean | false   | Skip TLS certificate verification     |
| `throw`                 | boolean | false   | Throw errors instead of logging       |
| `thresholds`            | object  | -       | Pass/fail criteria                    |
| `tags`                  | object  | -       | Tags for all metrics                  |
| `systemTags`            | array   | \[...]  | System tags to collect                |
| `summaryTrendStats`     | array   | \[...]  | Stats to show in summary              |
| `discardResponseBodies` | boolean | false   | Discard HTTP response bodies          |
| `noConnectionReuse`     | boolean | false   | Disable HTTP keep-alive               |
| `noVUConnectionReuse`   | boolean | false   | Close connections between iterations  |
| `minIterationDuration`  | string  | -       | Minimum iteration duration            |
| `noCookiesReset`        | boolean | false   | Don't reset cookies per iteration     |

## Next Steps

* Explore [Scenarios](/writing-tests/scenarios) for advanced execution control
* Learn about [Tags and Groups](/writing-tests/tags-groups) for organizing metrics
* Understand [Test Structure](/writing-tests/test-structure) fundamentals
