Skip to main content
The externally-controlled executor allows you to control k6 execution in real-time via the REST API. You can dynamically scale VUs up or down, pause and resume execution, and adjust test parameters while the test is running.

How It Works

With externally controlled execution:
  1. Test starts with initial vus and runs for duration (or indefinitely if duration is 0)
  2. VUs continuously loop through iterations
  3. You can control execution via the k6 REST API:
    • Scale VUs up or down
    • Pause and resume the test
    • Update the configuration dynamically
  4. Test runs until duration expires or you stop it manually

Configuration

string
required
Must be externally-controlled
integer
default:"0"
Initial number of VUs. Can be 0. Cannot be negative.
integer
default:"vus"
Maximum number of VUs that can be used during the test. Once set at test start, this cannot be decreased (only increased via API).
duration
required
Maximum test duration. Use 0 for infinite duration (test runs until manually stopped). Cannot be negative.
The gracefulStop option is NOT supported by this executor. VUs stop immediately when the test ends.

Example

Basic Setup

Run with the API enabled:

Infinite Duration Test

Start Paused

Then control via API to resume when ready.

API Control

The k6 REST API (enabled with --http-debug or environment variable) provides endpoints to control execution.

Get Current Status

Response:

Scale VUs

Pause Test

Resume Test

Scale and Adjust MaxVUs

When to Use

Use the externally controlled executor when:
  • You need dynamic control during test execution
  • You’re integrating k6 with external monitoring/alerting systems
  • You want to adjust load based on real-time application metrics
  • You’re building custom load testing dashboards
  • You need to manually respond to test conditions
  • You want to run exploratory performance testing
  • You’re implementing adaptive load testing algorithms

Behavior Details

Initial VUs and MaxVUs

At test start, k6 initializes maxVUs and activates vus of them:

Dynamic Scaling

Via API, you can scale vus up to maxVUs:

MaxVUs Constraints

You can increase maxVUs via API but cannot decrease it below the initial configuration value.

Duration Behavior

Finite duration:
Infinite duration:

Pause Behavior

When paused:
  • Running iterations complete
  • No new iterations start
  • VUs remain allocated
  • Test timer continues (for non-zero duration)

Not Distributable

The externally-controlled executor does NOT support distributed execution (execution segments). It can only run on a single k6 instance.

Common Patterns

Integration with Monitoring

Manual Exploratory Testing

Then manually control:

Dashboard Integration

Validation

Valid Configurations

Invalid Configurations

Metrics

Standard k6 metrics are emitted:
  • iterations - Total completed iterations
  • iteration_duration - Time per iteration
  • vus - Current number of active VUs (changes via API)
  • vus_max - Current maximum VUs (matches maxVUs config)

Best Practices

  1. Set high maxVUs: Allow plenty of headroom for scaling
  2. Start low: Begin with few VUs and scale up as needed
  3. Monitor carefully: Watch metrics when scaling to avoid overload
  4. Use infinite duration for exploration: duration: '0' for manual control
  5. Secure the API: Restrict access to the REST API in production
  6. Gradual scaling: Avoid jumping directly from 10 to 1000 VUs
  7. Test API integration: Ensure your control logic works before production
  8. Have a plan: Define scaling rules/criteria before running the test

Limitations

Key limitations of the externally-controlled executor:
  • No distributed execution support
  • Cannot use gracefulStop
  • Cannot decrease maxVUs below initial value
  • Cannot change duration once test starts
  • Cannot pause before test starts (use --paused flag instead)

See Also