What each executor supports at runtime
MaxoPerf can change five things about a running test: properties, virtual users, throughput, dropped-in config files, and pause / resume.
Not every engine supports all five. Engines differ in what they let you change after they start. When an engine cannot follow a control, the console shows it disabled with the reason, and the API rejects the change instead of accepting one that would do nothing.
The table below is generated from the capability table the product reads. The console uses it to decide what to enable, the API to decide what to accept, and the runner to pick an adapter. So the table always matches the product.
Several cells read requires …. The executor supports the control, but only for a script built
for it. Make your test controllable mid-run shows,
per engine, how to meet each of those preconditions.
How to read it
Section titled “How to read it”| Value | Meaning |
|---|---|
| Live | observable in the load within seconds of the change |
| Next iteration | written immediately, but only visible when your script next reads it |
| Not supported | the engine has no way to change this while it runs; the control is disabled with this reason |
| approximate | the engine has no setting for exactly this, so MaxoPerf maps it onto one it does have, and labels it wherever it appears |
requires … | supported, but only for a script that satisfies the stated precondition |
The mechanism in each cell is how the change reaches the engine:
jmeter-beanshell: JMeter’s BeanShell server on the container loopbackk6-rest: k6’s own REST API on the container loopbacklocust-runner: an in-process MaxoPerf greenlet that calls the same function as Locust’s own swarm endpointgatling-helper: the MaxoPerf classpath helper your simulation opts intoruntime-file: an atomically written file under/work/artifacts/maxoperf-runtime/, which any script on any executor can read
The matrix
Section titled “The matrix”| Executor | Properties | Virtual users | Throughput | Config file | Pause / resume |
|---|---|---|---|---|---|
ab | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
apiritif | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
external | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
gatling | Next iteration · runtime-file | Live · gatling-helper — requires gatling.maxoperf-helper | Live · gatling-helper — requires gatling.maxoperf-helper | Live · runtime-file | Live · gatling-helper — requires gatling.maxoperf-helper |
grinder | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
jmeter | Live · jmeter-beanshell | Live · jmeter-beanshell — requires jmeter.concurrency-thread-group | Live · jmeter-beanshell — requires jmeter.throughput-timer | Live · runtime-file | Live · jmeter-beanshell — requires jmeter.concurrency-thread-group |
junit | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
k6 | Next iteration · runtime-file | Live · k6-rest — requires k6.externally-controlled | Live · k6-rest — approximate — requires k6.externally-controlled | Live · runtime-file | Live · k6-rest — requires k6.externally-controlled |
locust | Live · locust-runner | Live · locust-runner | Not supported | Live · runtime-file | Live · locust-runner |
molotov | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
mocha | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
pbench | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
playwright | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
robot | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
scalable | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
selenium | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
siege | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
taurus | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
testng | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
tsung | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
vegeta | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
wdio | Next iteration · runtime-file | Not supported | Not supported | Live · runtime-file | Not supported |
What the preconditions mean
Section titled “What the preconditions mean”| Precondition id | What it needs |
|---|---|
jmeter.concurrency-thread-group | Your plan drives its threads with a Concurrency Thread Group. Classic, Stepping and Ultimate thread groups read their thread count only once, when the plan loads, so nothing can move it while the test runs. |
jmeter.throughput-timer | Your plan contains a Constant Throughput Timer. It re-reads its target on every sample, so MaxoPerf can move the rate mid-run; a plan without one has nothing to move. (A Throughput Shaping Timer keeps its schedule in a load_profile table rather than a single target, and cannot be steered live — swap it for a Constant Throughput Timer if you want this control.) |
k6.externally-controlled | The active k6 scenario uses the externally-controlled executor. Every other k6 executor computes its own VU schedule and refuses to be steered. |
gatling.maxoperf-helper | Your simulation reads the MaxoPerf helper (com.maxoperf.gatling.MaxoPerf). Gatling open source has no runtime injection API, so a simulation that has not opted in cannot be steered at all. |
When a control is disabled
Section titled “When a control is disabled”The console tells three cases apart and says which one applies:
- Not supported for this executor. There is nothing to enable. Locust throughput is an example. Locust models load as users × wait time and has no rate primitive, so an “RPS” control would change a different number and call it RPS.
- Precondition unmet. The executor supports the control, but this script does not qualify. The
hint is the
requiresid from the table above, and the API returns422 CONTROL_PRECONDITION_UNMETwith the same id. Change the script (or the thread group, or the k6 executor) and the control is enabled on the next run. - Run not running. Controls exist only for a live run. A finished run’s Live tab is read-only.