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 can do all five. Engines differ in what they will let anything change after they have started, and MaxoPerf will not pretend otherwise: a control an engine cannot follow is rendered disabled with the reason, and the API rejects it rather than accepting a change that would silently do nothing.

The table below is generated from the same capability table the product itself reads — the console uses it to decide what to enable, the API uses it to decide what to accept, and the runner uses it to decide which adapter to use. It cannot disagree with the product.

Several cells read requires : the executor can do it, but only for a script that is built for it. Make your test controllable mid-run is the per-engine recipe for satisfying 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 knob for exactly this, so MaxoPerf projects it onto one it does have — labelled everywhere it appears
requires supported, but only for a script that satisfies the stated precondition

The mechanism in each cell is how the change physically 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 calling the same function Locust’s own swarm endpoint calls
  • gatling-helper — the MaxoPerf classpath helper your simulation opts into
  • runtime-file — an atomically written file under /work/artifacts/maxoperf-runtime/, readable by any script on any executor
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-restapproximate — requires k6.externally-controlledLive · runtime-fileLive · k6-rest
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 distinguishes three cases, and says which one applies:

  1. Not supported for this executor. There is nothing to enable. Locust throughput is the clearest example: Locust models load as users × wait time and has no rate primitive at all, so an “RPS” control would be a different number wearing an RPS label.
  2. Precondition unmet. The executor supports it, 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 lights up on the next run.
  3. Run not running. Controls exist only for a live run; a finished run’s Live tab is read-only.