skip to content

In JMeter's Uniform Random Timer, what pause do Constant Delay Offset 300 and Random Delay Maximum 700 produce?

level: juniorimportance: must knowfreq 72%

answer

  1. Two numeric fields, both in milliseconds
  2. One value is paid on every pause
  3. The other bounds a random component
  4. The thread sleeps for the sum

basics

~10 s

Each pause is 300 ms plus a uniformly drawn value between 0 and 700 ms, so the thread waits somewhere from 300 to 1000 ms before every sampler the timer holds.

solid answer

~40 s

`UniformRandomTimer` computes `Math.abs(random.nextDouble() * range + offset)`, where `range` is the **Random Delay Maximum** field and `offset` is the **Constant Delay Offset** field. Both are milliseconds. With 300 and 700 the pause is spread evenly over 300 ms to 1000 ms, every value in that window equally likely; the offset is a floor that is always paid, not a midpoint. In the `.jmx` the fields are saved as `ConstantTimer.delay` and `RandomTimer.range`, because `UniformRandomTimer` extends `RandomTimer`, which extends `ConstantTimer`. JMeter serves the timer *before* the sampler it is scoped to, and when several timers share a scope their delays are summed into one sleep.

code

xml · 5 lines
xml
<UniformRandomTimer guiclass="UniformRandomTimerGui" testclass="UniformRandomTimer" testname="Uniform Random Timer" enabled="true">
  <stringProp name="ConstantTimer.delay">300</stringProp>
  <stringProp name="RandomTimer.range">700</stringProp>
</UniformRandomTimer>
<hashTree/>

go deeper

for a junior

Recall that both fields are milliseconds and that the pause is offset plus a random draw capped by the maximum. Being able to state the 300 ms to 1000 ms window is the whole of the expected answer.

for a middle

Explain the mechanics: nextDouble scaled by the range, added to the offset, drawn per thread from ThreadLocalRandom, and stored in the .jmx under the inherited ConstantTimer.delay and RandomTimer.range names.

for a senior

Show that you check placement and arithmetic together: which samplers the timer holds, that timers in one scope sum into a single sleep, and that a non-numeric field degrades to zero rather than failing the run.

for a principal

Own the convention. Decide whether pause values are hard-coded per plan or parameterised, and whether the team relies on the timer.factor property to rescale them, since that lever reaches only the three random timers.

## The formula behind the two fields The Uniform Random Timer has exactly two numeric fields and it adds them: ```java // UniformRandomTimer.delay() return (long) Math.abs((getRandom().nextDouble() * getRange()) + super.delay()); ``` - `getRange()` is the **Random Delay Maximum** field, in milliseconds. - `super.delay()` is `ConstantTimer.delay()`, which returns the **Constant Delay Offset** field, in milliseconds. - `getRandom()` hands back `ThreadLocalRandom.current()`, so each thread draws independently and threads do not contend on one shared generator. `nextDouble()` yields a value in `[0.0, 1.0)`, so the random component lands in `[0, 700)` and the total in `[300, 1000)`. The distribution is flat: 310 ms and 940 ms are equally likely. The `Math.abs` call is inherited boilerplate here — with a non-negative offset and a non-negative range the sum can never go negative — but it matters in the sibling Gaussian timer. ## The random-timer family shares one base class All three random timers extend `RandomTimer`, so they reuse the same two stored properties and differ only in how the random component is drawn. | Timer | GUI field for the random part | What the field means | Second field | |---|---|---|---| | Uniform Random Timer | Random Delay Maximum | upper bound of a flat draw | Constant Delay Offset | | Gaussian Random Timer | Deviation | standard deviation of the draw | Constant Delay Offset | | Poisson Random Timer | Lambda | mean of the Poisson draw | Constant Delay Offset | The Constant Timer is the degenerate case: it has one field, **Thread Delay**, and returns it unchanged. ## What the .jmx actually stores Because the class hierarchy is `UniformRandomTimer -> RandomTimer -> ConstantTimer`, the saved property names do not match the class you dragged into the tree: ```xml <UniformRandomTimer guiclass="UniformRandomTimerGui" testclass="UniformRandomTimer" testname="Uniform Random Timer" enabled="true"> <stringProp name="ConstantTimer.delay">300</stringProp> <stringProp name="RandomTimer.range">700</stringProp> </UniformRandomTimer> ``` That is worth knowing when you grep a plan or diff one in review: searching for `UniformRandomTimer.range` finds nothing, and `ConstantTimer.delay` appears under the Gaussian and Poisson timers too. ## Where the timer applies A timer is not attached to an iteration; it is attached to a **scope**. JMeter serves every timer in a sampler's scope before that sampler runs, sums their delays, and sleeps once. Placement therefore decides everything: 1. As a child of one HTTP Request, the timer runs only before that request. 2. Directly under a Thread Group, it runs before *every* sampler in the group. 3. Under a controller, it runs before every sampler that controller holds. 4. With no sampler anywhere in its scope, it never runs at all. ## Traps this timer sets - **The offset is not optional in effect.** Leaving Constant Delay Offset empty gives you a pause between 0 and the maximum, which is a different profile from the one most people intend. - **A non-numeric field is silently zero.** Both fields are read through `getPropertyAsLong` / `getPropertyAsDouble`, whose string conversion catches `NumberFormatException` and returns `0`. Put an unresolved variable reference in the Constant Delay Offset and JMeter does not fail: the unset reference renders as the literal text `${PAUSE}`, the conversion returns `0`, and the run continues with only the random half of the pause. - **The values are milliseconds, not seconds.** `Random Delay Maximum` of `2` is two milliseconds. - **Two timers in the same scope add up.** Dropping a second Uniform Random Timer beside the first does not replace it; the thread sleeps for the sum of the two draws. - **`timer.factor` can rescale it behind your back.** That JMeter property multiplies the computed delay of the Uniform, Gaussian and Poisson timers, so a plan that pauses less than its fields say may be running on a machine where that property is set.

  • What does the Uniform Random Timer do if its Constant Delay Offset holds an unresolved ${PAUSE} reference?
    Nothing loud. An unset variable reference is not blanked out; it renders as the literal text ${PAUSE}. ConstantTimer reads the field with getPropertyAsLong, whose string conversion catches the NumberFormatException and returns 0, so the offset quietly becomes 0 ms and the run continues with only the random component.
  • Where do you place a Uniform Random Timer so it pauses before only one HTTP Request?
    Make it a child of that sampler. A timer applies to every sampler in its scope, so at Thread Group level it fires before all of them, and as a child of one request it fires only for that request. A timer with no sampler in its scope is never processed at all.

saying these in an interview costs you the question

  • Says the pause is between 0 and 700 ms, ignoring the offset entirely.
  • Treats Random Delay Maximum as the total pause rather than an addition.
  • Claims the timer runs after the sampler and its response.
  • Assumes an unparsable value in either field aborts the run.
  • Thinks two timers in one scope override each other instead of summing.
  • Reads the fields as seconds rather than milliseconds.