Skip to main content
Executors control how k6 schedules VUs and iterations. They are the building blocks of k6 test execution, determining:
  • How many VUs run
  • When VUs start and stop
  • Whether iterations are shared or per-VU
  • Whether execution is time-based or iteration-based

Executor Types

k6 provides 8 executor types, each optimized for different testing scenarios:

Iteration-Based Executors

These executors run a fixed number of iterations:

Time-Based Executors with Fixed VUs

These executors run VUs for a specified duration:

Arrival Rate Executors

These executors start iterations at a fixed rate, regardless of iteration duration:

Special Executors

Configuration

Executors are configured in the scenarios section of your k6 options:
export const options = {
  scenarios: {
    my_scenario: {
      executor: 'constant-vus',
      vus: 10,
      duration: '30s',
    },
  },
};

Common Configuration Options

All executors share these base configuration options:
executor
string
required
The executor type (e.g., constant-vus, ramping-arrival-rate)
startTime
duration
default:"0s"
Time offset since the start of the test when this executor should begin
gracefulStop
duration
default:"30s"
Time to wait for iterations to finish executing before stopping them forcefully. Not supported by externally-controlled.
exec
string
default:"default"
Name of the exported JS function to execute
env
object
Environment variables specific to this executor
tags
object
Tags to set for all metrics emitted by this executor

Choosing an Executor

Use Iteration-Based Executors When:

  • You need to run a specific number of test iterations
  • You want to ensure all test data is processed
  • You’re running data-driven tests with a fixed dataset

Use Time-Based Executors When:

  • You want to test system behavior over a time period
  • You’re simulating real user behavior patterns
  • You need predictable test duration

Use Arrival Rate Executors When:

  • You need to test at specific requests-per-second rates
  • Iteration duration varies significantly
  • You want to model realistic traffic patterns with variable load
  • You need to ensure a constant throughput regardless of response times

Use Externally Controlled Executor When:

  • You need dynamic control during test execution
  • You’re integrating k6 with other tools or dashboards
  • You want to manually adjust load based on real-time observations

Graceful Stop

The gracefulStop option (default: 30s) gives running iterations time to complete when the executor’s regular duration ends:
export const options = {
  scenarios: {
    my_scenario: {
      executor: 'constant-vus',
      vus: 10,
      duration: '5m',
      gracefulStop: '30s', // Wait up to 30s for iterations to finish
    },
  },
};
If an iteration doesn’t complete within the graceful stop period, it’s interrupted.

Multiple Scenarios

You can run multiple executors simultaneously:
export const options = {
  scenarios: {
    smoke_test: {
      executor: 'constant-vus',
      vus: 1,
      duration: '1m',
    },
    load_test: {
      executor: 'ramping-vus',
      startTime: '1m', // Start after smoke test
      startVUs: 0,
      stages: [
        { duration: '2m', target: 50 },
        { duration: '5m', target: 50 },
        { duration: '2m', target: 0 },
      ],
    },
  },
};

Execution Segments

All executors except externally-controlled support distributed execution via execution segments. This allows you to split test execution across multiple k6 instances.

Next Steps

Shared Iterations

Run a fixed total number of iterations

Constant VUs

Maintain constant VUs over time

Ramping VUs

Gradually increase/decrease VUs

Constant Arrival Rate

Fixed iterations per second

Build docs developers (and LLMs) love