skip to content

Multi-Engine Runs

Driving several engines from one controller over RMI, and the long list of things that change when you do: load is not divided, data files stay put, and every sample funnels back.

on this pageshow

explore

questions

20

In JMeter, how do the -r and -R command-line flags differ?

level: juniorimportance: must knowfreq 64%

answer

  1. Both are refused outside non-GUI mode
  2. One of the two takes no argument
  3. A JMeter property supplies the default list
  4. The uppercase form carries the hosts itself

basics

~10 s

Both start a JMeter run on remote server processes instead of locally. -r uses the host list already in the remote_hosts property; -R takes the list inline and overrides it.

solid answer

~40 s

In a non-GUI JMeter run, `-r` (`--runremote`) takes no argument and drives the hosts named by the `remote_hosts` JMeter property; the shipped `bin/jmeter.properties` at 6.0.0 sets that to `127.0.0.1`, and JMeter falls back to `127.0.0.1` in code if the property is missing. `-R` (`--remotestart`) carries its own comma-separated list, as in `jmeter -n -t plan.jmx -R gen1,gen2,gen3,gen4`, and that list wins for the run. Each entry may be `host` or `host:port`; a bare host is looked up on the port given by `server.rmi.port`, default `1099`. Both flags demand `-n` and `-t`: JMeter refuses a GUI launch with `-r and -R and -X are only valid in non-GUI mode`, and a non-GUI launch with no plan with `Non-GUI runs require a test plan`.

code

bash · 11 lines
bash
# on each generator, first
jmeter-server

# on the laptop: hosts come from remote_hosts in bin/jmeter.properties
jmeter -n -t plan.jmx -l run.jtl -r

# on the laptop: hosts given inline, overriding remote_hosts
jmeter -n -t plan.jmx -l run.jtl -R gen1,gen2,gen3,gen4

# gen4 was started with SERVER_PORT=1234
jmeter -n -t plan.jmx -l run.jtl -R gen1,gen2,gen3,gen4:1234

go deeper

for a junior

Recall that -r and -R both belong to a non-GUI JMeter run, that -R carries the hosts itself, and that both need -n and -t on the same command line.

for a middle

Explain where the host list comes from when only -r is given, that the shipped remote_hosts is 127.0.0.1, and that a bare entry is looked up on port 1099 unless you write host:port.

for a senior

Show that you check the controller's console for the per-host 'Configuring remote engine' lines before blaming the network, and that you know the flags neither start nor stop the server processes.

for a principal

Decide whether the host list belongs in a checked-in properties file or on the command line, so that the same plan can be pointed at different generator sets without editing anything under version control.

## The two flags in one line `-r` and `-R` both switch a JMeter CLI run from *drive the plan here* to *drive it on engines this process does not host*. They differ only in where the host list comes from. | Flag | Long form | Argument | Host list source | |---|---|---|---| | `-r` | `--runremote` | none | the `remote_hosts` JMeter property | | `-R` | `--remotestart` | required | the comma-separated list you type after it | `-R` is not "`-r` plus a list". It is a separate option and it is sufficient on its own: JMeter looks for `-R` first and only falls back to `-r` when `-R` is absent. Passing both is harmless, and `-R` wins. ## Where the list really comes from At Apache JMeter 6.0.0 the shipped `bin/jmeter.properties` carries this line **uncommented**: ```properties remote_hosts=127.0.0.1 ``` So a bare `-r` on an untouched installation targets the loopback address rather than failing with an obvious "you configured nothing" message. If you delete the property outright, JMeter still falls back to `127.0.0.1` in code, so the behaviour is the same either way. Each entry in either list is trimmed and may be written two ways: - a bare `host`, which is looked up on the port named by the `server.rmi.port` property, default `1099`; - `host:1234`, which overrides that for this entry alone — the form you need when a generator was started with a non-default `SERVER_PORT`; - an IPv6 literal in brackets works too, because JMeter looks for the port separator only after the closing `]`. ## Four engines from one laptop With `jmeter-server` already running on `gen1` through `gen4`, the laptop is the controller: ```bash # host list taken from remote_hosts in bin/jmeter.properties jmeter -n -t plan.jmx -l run.jtl -r # host list given inline, overriding remote_hosts for this run only jmeter -n -t plan.jmx -l run.jtl -R gen1,gen2,gen3,gen4 # one generator was started with SERVER_PORT=1234 jmeter -n -t plan.jmx -l run.jtl -R gen1,gen2,gen3,gen4:1234 ``` The controller prints `Configuring remote engine: gen1` for each host, then `Starting distributed test with remote engines: [gen1, gen2, gen3, gen4]`, and the process stays alive until every engine has reported that its test ended. ## Both flags are non-GUI only JMeter checks the combination before it does anything else. If `-n` is missing and any of `-r`, `-R` or `-X` is present, it refuses to start and prints: ```text Error: -r and -R and -X are only valid in non-GUI mode ``` `-t` is equally mandatory — a non-GUI run with no plan fails with `Non-GUI runs require a test plan`. Inside the GUI the equivalent controls are the **Run > Remote Start** and **Remote Start All** menu items, which read the same `remote_hosts` property; the flags are simply not wired into that path. ## What these flags do not do 1. **They do not copy the plan.** Nothing is written to the generators. The controller parses `plan.jmx` locally, clones the resulting tree and sends it over RMI, so the `.jmx` file never has to exist on `gen1`–`gen4`. 2. **They do not start the server processes.** `bin/jmeter-server` must already be running on each host; if it is not, the controller fails to find a bound engine there. 3. **They do not assign `remote_hosts`.** The JMeter manual describes `-R list` as equivalent to `-r` plus `-Jremote_hosts=list`, but at 6.0.0 the code hands the `-R` argument straight to the distributed runner and never writes it into the property. Anything on the controller that reads `remote_hosts` as a property still sees the value from the file. 4. **They do not shut the servers down.** Once the run ends the engines are still resident and ready for the next controller, unless you also pass `-X`.

  • The JMeter manual calls -R equivalent to -r plus -Jremote_hosts=<list>. Where does that equivalence break down?
    For the run itself it holds, but at 6.0.0 JMeter never assigns the list to the property: the -R argument is passed straight to the distributed runner, and `remote_hosts` is only ever read, never written. So anything on the controller that consults `remote_hosts` as a property still sees the value from jmeter.properties.
  • What happens if you run jmeter -n -t plan.jmx -r on a machine where no JMeter server process is running?
    The controller targets 127.0.0.1, the value the shipped remote_hosts carries, finds no engine bound there, and with client.continue_on_fail at its default of false it stops and throws `Following remote engines could not be configured:[127.0.0.1]`. It is the commonest first-run surprise, and it looks like a network fault rather than a configuration gap.

saying these in an interview costs you the question

  • Thinks -R works from the JMeter GUI without -n.
  • Believes -r copies the .jmx file out to each server first.
  • Says -R has to be combined with -r; -R alone already starts the remote run.
  • Assumes remote_hosts entries must be bare hostnames, so host:port is rejected.
  • Expects -r to accept a host list as its argument.
open as a page

In JMeter 6, why does a distributed run refuse to start without rmi_keystore.jks?

level: juniorimportance: must knowfreq 55%

basics

~20 s

Since JMeter 4.0 the RMI transport runs over SSL by default: server.rmi.ssl.disable is false. The keystore that server.rmi.ssl.keystore.file names, rmi_keystore.jks, is not in the download, so you generate it and copy it to every node.

open as a page

What does JMeter's bin/jmeter-server script actually start on a load generator?

level: middleimportance: must knowfreq 68%

basics

~10 s

It launches JMeter with -s, which starts a long-lived engine process that registers itself for remote calls and then waits. It holds no test plan until a controller sends one.

open as a page

A JMeter Thread Group asks for 1,000 threads and the plan runs on six remote engines - how many threads hit the target?

level: middleimportance: must knowfreq 74%

basics

~10 s

Six thousand. JMeter never splits a plan across engines: the controller sends the whole plan to each one, so the Thread Group's 1,000 threads start once per server. You do the division, not JMeter.

open as a page

What does JMeter's mode property select for a distributed run, and what is its default?

level: middleimportance: must knowfreq 61%

basics

~10 s

JMeter's mode property names the SampleSender each engine uses to return results to the controller. It is read on the controller only, and defaults to StrippedBatch: batched sends with response bodies removed.

open as a page

Which JMeter properties fix the RMI ports of a distributed run so a firewall can allow them?

level: middleimportance: must knowfreq 62%

basics

~10 s

Three ports, three properties. server.rmi.port pins the engine's RMI registry, default 1099. server.rmi.localport pins the engine object itself, dynamic by default. client.rmi.localport pins the controller's two result-callback ports, also dynamic by default.

open as a page

A JMeter CSV Data Set Config feeds unique logins across six engines - why does every engine issue the same rows?

level: seniorimportance: must knowfreq 62%

basics

~20 s

Every engine holds its own copy of the file and its own read position, so all six start at line one and walk the same rows in step. Sharing mode scopes threads inside one JVM and never reaches across engines.

open as a page

Six JMeter engines stream samples and the controller's heap keeps filling. Which mode change helps most?

level: seniorimportance: must knowfreq 49%

basics

~20 s

Move to mode=Statistical. It is the only value that cuts the number of results reaching the controller rather than their size, replacing each label's samples with one aggregate. Stripping and batching only shrink or group what still arrives.

open as a page

In a JMeter distributed run, what does the controller actually send to each remote engine?

level: juniorimportance: should knowfreq 50%

basics

~20 s

The serialised test plan, the script name, a relative base directory, and any properties the controller was told to push. Nothing else. Data files, external script files and element classes must already exist on every server.

open as a page

After a distributed JMeter run, why does the controller's result file hold no response bodies?

level: juniorimportance: should knowfreq 52%

basics

~10 s

JMeter's mode property defaults to StrippedBatch, and every Stripped sender blanks each SampleResult's response data on the engine before it is sent. Timings, byte counts and status codes survive; the payload does not.

open as a page

In a JMeter distributed run, which JVMs does the -G flag set properties in?

level: middleimportance: should knowfreq 54%

basics

~10 s

Only the remote servers. JMeter collects -G values on the controller and pushes them to every engine just before the run starts; the controller's own JMeter properties are left unchanged.

open as a page

In JMeter's Batch sending mode, which two properties decide when an engine flushes samples?

level: middleimportance: should knowfreq 43%

basics

~10 s

num_sample_threshold, default 100 samples, and time_threshold, default 60000 milliseconds. Whichever fires first sends the accumulated batch and resets both counters. Setting either to -1 disables that trigger.

open as a page

One of four JMeter remote engines is unreachable at startup. Which properties decide whether the run continues?

level: seniorimportance: should knowfreq 52%

basics

~10 s

Three controller-side properties decide it: client.tries, client.retries_delay and client.continue_on_fail. Their defaults are one attempt, a five-second gap between attempts, and abort the run if any engine fails.

open as a page

A JMeter plan reads a property that is set only on the controller - what do the remote engines resolve it to?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Whatever that engine's own property set holds, which is usually nothing. Each engine evaluates the plan in its own JVM against properties it loaded at its own startup; the controller's property set does not travel with the plan.

open as a page

A JMeter remote run starts behind a corporate firewall but no samples arrive. Which RMI leg is blocked?

level: seniorimportance: should knowfreq 44%

basics

~20 s

The return leg. The registry and engine ports are open, since the plan is running, but the engine cannot connect back to the controller's callback ports. Pin them with client.rmi.localport and allow them inbound on the controller.

open as a page

How would you decide whether a JMeter generator fleet keeps RMI SSL or sets server.rmi.ssl.disable=true?

level: principalimportance: should knowfreq 30%

basics

~20 s

Decide what reaching an engine's RMI port should be worth. The default buys mutual authentication and costs a shared keystore on every node. Disabling it removes the file and leaves an engine that runs any plan it is handed.

open as a page

In a JMeter plan replicated to six engines, what do ${__machineName} and ${__machineIP} return on each one?

level: middleimportance: nice to knowfreq 32%

basics

~10 s

The host name and IP address of the machine that evaluates them - so each engine returns its own. They are the built-in way to tell six identical copies of one replicated plan apart.

open as a page

In JMeter, how does the controller's -X flag differ from the server.exitaftertest property?

level: seniorimportance: nice to knowfreq 40%

basics

~10 s

-X is a controller-side choice made per run: when the test ends it tells every engine that controller started to exit. server.exitaftertest is a standing rule read by the server itself at startup.

open as a page

In JMeter's Asynch sending mode, what happens when the asynch.batch.queue.size queue fills?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

The sampler thread blocks. AsynchSampleSender first tries a non-blocking offer; when that fails it falls back to a blocking put and waits for the worker to drain space, counting the wait in QueueWaits and QueueWaitTime.

open as a page

Why does a JMeter distributed setup that ran last week suddenly fail its RMI connection?

level: seniorimportance: nice to knowfreq 20%

basics

~10 s

The stock keystore expires. JMeter's bin/create-rmi-keystore.sh and .bat call keytool with -validity 7, so the rmi_keystore.jks they produce is good for seven days. Nothing on either node changed; the key pair simply aged out.

open as a page