Skip to content

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.

ValueMeaning
Liveobservable in the load within seconds of the change
Next iterationwritten immediately, but only visible when your script next reads it
Not supportedthe engine has no way to change this while it runs; the control is disabled with this reason
approximatethe 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 loopback
  • k6-rest: k6’s own REST API on the container loopback
  • locust-runner: an in-process MaxoPerf greenlet that calls the same function as Locust’s own swarm endpoint
  • gatling-helper: the MaxoPerf classpath helper your simulation opts into
  • runtime-file: an atomically written file under /work/artifacts/maxoperf-runtime/, which any script on any executor can read
ExecutorPropertiesVirtual usersThroughputConfig filePause / resume
abNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
apiritifNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
externalNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
gatlingNext iteration · runtime-fileLive · gatling-helper — requires gatling.maxoperf-helperLive · gatling-helper — requires gatling.maxoperf-helperLive · runtime-fileLive · gatling-helper — requires gatling.maxoperf-helper
grinderNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
jmeterLive · jmeter-beanshellLive · jmeter-beanshell — requires jmeter.concurrency-thread-groupLive · jmeter-beanshell — requires jmeter.throughput-timerLive · runtime-fileLive · jmeter-beanshell — requires jmeter.concurrency-thread-group
junitNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
k6Next iteration · runtime-fileLive · k6-rest — requires k6.externally-controlledLive · k6-rest — approximate — requires k6.externally-controlledLive · runtime-fileLive · k6-rest — requires k6.externally-controlled
locustLive · locust-runnerLive · locust-runnerNot supportedLive · runtime-fileLive · locust-runner
molotovNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
mochaNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
pbenchNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
playwrightNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
robotNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
scalableNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
seleniumNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
siegeNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
taurusNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
testngNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
tsungNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
vegetaNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
wdioNext iteration · runtime-fileNot supportedNot supportedLive · runtime-fileNot supported
Precondition idWhat it needs
jmeter.concurrency-thread-groupYour 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-timerYour 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-controlledThe active k6 scenario uses the externally-controlled executor. Every other k6 executor computes its own VU schedule and refuses to be steered.
gatling.maxoperf-helperYour 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.

The console tells three cases apart and says which one applies:

  1. 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.
  2. Precondition unmet. The executor supports the control, but this script does not qualify. The hint is the requires id from the table above, and the API returns 422 CONTROL_PRECONDITION_UNMET with the same id. Change the script (or the thread group, or the k6 executor) and the control is enabled on the next run.
  3. Run not running. Controls exist only for a live run. A finished run’s Live tab is read-only.