> ## 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.

# Constant VUs Executor

> Run a fixed number of VUs for a specified duration

The `constant-vus` executor runs a fixed number of VUs for a specified duration. This is one of the simplest executors and is ideal for steady-state load testing where you want to maintain constant concurrent users.

## How It Works

With constant VUs:

1. A fixed number of VUs start executing
2. Each VU runs iterations in a loop
3. Execution continues for the specified duration
4. VUs run as many iterations as they can complete
5. All VUs stop when duration expires (plus gracefulStop)

```
VUs ^  
  3 |████████████████████████████
  2 |████████████████████████████
  1 |████████████████████████████
  0 +-----------------------------> time
    0s        duration         end
```

## Configuration

<ParamField path="executor" type="string" required>
  Must be `constant-vus`
</ParamField>

<ParamField path="vus" type="integer" default="1">
  Number of VUs to run concurrently. Must be greater than 0.
</ParamField>

<ParamField path="duration" type="duration" required>
  Total duration of the executor. Must be at least 1 second.
</ParamField>

## Example

### Basic Load Test

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

export const options = {
  scenarios: {
    constant_load: {
      executor: 'constant-vus',
      vus: 10,
      duration: '5m',
    },
  },
};

export default function () {
  http.get('https://test.k6.io');
  sleep(1);
}
```

This maintains 10 concurrent VUs for 5 minutes, each VU continuously looping through iterations.

### With Thresholds

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

export const options = {
  scenarios: {
    steady_state: {
      executor: 'constant-vus',
      vus: 50,
      duration: '10m',
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<500'], // 95% of requests under 500ms
    http_req_failed: ['rate<0.01'],   // Less than 1% errors
  },
};

export default function () {
  http.get('https://test.k6.io/api/data');
  sleep(1);
}
```

### Multiple Constant Load Scenarios

```javascript theme={null}
export const options = {
  scenarios: {
    light_load: {
      executor: 'constant-vus',
      vus: 5,
      duration: '2m',
      startTime: '0s',
      tags: { load_level: 'light' },
    },
    medium_load: {
      executor: 'constant-vus',
      vus: 20,
      duration: '5m',
      startTime: '2m',
      tags: { load_level: 'medium' },
    },
    heavy_load: {
      executor: 'constant-vus',
      vus: 50,
      duration: '3m',
      startTime: '7m',
      tags: { load_level: 'heavy' },
    },
  },
};
```

## When to Use

Use the constant VUs executor when:

* You want to maintain a steady load on your system
* You're testing how the system performs under sustained concurrent users
* You need predictable, consistent load over time
* You're establishing performance baselines
* You want to verify system stability under constant load
* You're running soak tests to detect memory leaks or degradation

## Behavior Details

### Iteration Loop

Each VU continuously executes the default function in a loop until duration expires:

```javascript theme={null}
export default function () {
  // This function runs repeatedly for each VU
  // VU 1: iteration 0, 1, 2, 3, 4...
  // VU 2: iteration 0, 1, 2, 3, 4...
  console.log(`VU ${__VU}, iteration ${__ITER}`);
}
```

### No Fixed Iteration Count

Unlike iteration-based executors, there's no predetermined number of iterations. VUs run as many iterations as they can:

```javascript theme={null}
// Fast iterations (100ms each) might complete 600 iterations in 1 minute
// Slow iterations (5s each) might complete 12 iterations in 1 minute
```

### Graceful Stop

When duration expires, running iterations have `gracefulStop` time to complete:

```javascript theme={null}
export const options = {
  scenarios: {
    example: {
      executor: 'constant-vus',
      vus: 10,
      duration: '5m',
      gracefulStop: '30s', // Allow 30s for iterations to finish
    },
  },
};
```

Execution timeline:

* 0s - 5m: Regular execution, new iterations can start
* 5m - 5m30s: Graceful stop period, no new iterations, existing ones finish
* 5m30s: All VUs forcefully stopped

## Metrics

The executor emits these metrics:

* `iterations` - Total completed iterations
* `iteration_duration` - Time to complete each iteration
* `vus` - Number of active VUs (constant at configured value)
* `vus_max` - Maximum number of VUs (same as vus)

## Common Patterns

### Soak Testing

Test system stability over extended periods:

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

export const options = {
  scenarios: {
    soak: {
      executor: 'constant-vus',
      vus: 20,
      duration: '4h', // Long duration to detect leaks
    },
  },
};

export default function () {
  http.get('https://test.k6.io');
  sleep(1);
}
```

### Steady Background Load

Maintain background load while testing something else:

```javascript theme={null}
export const options = {
  scenarios: {
    background: {
      executor: 'constant-vus',
      vus: 10,
      duration: '30m',
      exec: 'background',
    },
    spike: {
      executor: 'ramping-vus',
      startTime: '10m',
      startVUs: 0,
      stages: [
        { duration: '1m', target: 100 },
        { duration: '5m', target: 100 },
        { duration: '1m', target: 0 },
      ],
      exec: 'spike',
    },
  },
};

export function background() {
  http.get('https://test.k6.io/background');
}

export function spike() {
  http.get('https://test.k6.io/spike');
}
```

### Different Iteration Speeds

```javascript theme={null}
import http from 'k6/http';
import { sleep } from 'k6';
import { randomIntBetween } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

export const options = {
  scenarios: {
    variable_think_time: {
      executor: 'constant-vus',
      vus: 25,
      duration: '10m',
    },
  },
};

export default function () {
  http.get('https://test.k6.io');
  // Simulate realistic user think time variation
  sleep(randomIntBetween(1, 5));
}
```

## Comparison with Other Executors

| Feature        | Constant VUs | Ramping VUs   | Shared Iterations |
| -------------- | ------------ | ------------- | ----------------- |
| VU count       | Fixed        | Variable      | Fixed             |
| Duration       | Fixed        | Sum of stages | Up to maxDuration |
| Iterations     | Unlimited    | Unlimited     | Fixed total       |
| Best for       | Steady load  | Variable load | Fixed work        |
| Predictability | High         | Medium        | Low (per VU)      |

## Best Practices

1. **Set realistic duration**: Ensure duration matches your test objectives
2. **Include think time**: Use `sleep()` to simulate realistic user behavior
3. **Monitor resource usage**: Watch system resources throughout the constant load
4. **Use for baselines**: Great for establishing performance baselines before ramping tests
5. **Configure gracefulStop**: Allow enough time for iterations to complete cleanly
6. **Consider iteration duration**: Faster iterations = more iterations = more load

## Duration Requirements

<Warning>
  The duration must be at least 1 second. For very short tests, consider using iteration-based executors instead.
</Warning>

```javascript theme={null}
// ❌ Invalid - duration too short
{
  executor: 'constant-vus',
  vus: 10,
  duration: '500ms', // Error!
}

// ✓ Valid
{
  executor: 'constant-vus',
  vus: 10,
  duration: '1s', // OK
}
```

## See Also

* [Ramping VUs](/executors/ramping-vus) - Variable VU count over time
* [Constant Arrival Rate](/executors/constant-arrival-rate) - Fixed iteration rate regardless of VUs
* [Shared Iterations](/executors/shared-iterations) - Fixed iteration count instead of duration
