skip to content

A JMeter Open Model Thread Group run ends with failed, cut-short samples. What in the schedule causes that?

level: seniorimportance: should knowfreq 44%

answer

  1. Look at the very end of the run
  2. The starter does not wait politely
  3. Check jmeter.log before the result file
  4. One step kind buys wall-clock time
  5. Rate steps occupy no duration at all

basics

~20 s

The schedule ran out. An Open Model Thread Group interrupts its threads as soon as the last arrivals or pause step elapses, cancelling in-flight samplers, so those iterations land as failures. Append a pause step to buy them time.

solid answer

~40 s

The Open Model Thread Group ends the moment its schedule ends. Once the starter has issued the last arrival and waited out the remaining duration, it stops and interrupts every thread still running: samplers that implement `Interruptible` — the HTTP samplers among them — have their in-flight request cancelled, so those samples come back marked failed rather than being allowed to complete. `jmeter.log` says so explicitly, naming the count of live threads and suggesting the fix. That fix is to append a `pause(...)` long enough for the slowest iteration to finish, because a pause adds duration to the schedule while scheduling no new arrivals. Sizing it is a judgement call: too short and you keep truncating the tail, too long and every run carries dead wall-clock time.

code

text · 1 line
text
Test schedule finished, however, there are 37 thread(s) still running. Will interrupt the threads. If you want to keep some time for the threads to complete, consider adding pause(10 min) at the end of the schedule.

go deeper

for a junior

Recall that the run stops when the schedule stops, and that a pause step at the end is what gives already-started work time to finish.

for a middle

Explain that the starter waits out the schedule's total duration and then interrupts survivors, cancelling in-flight samplers, so the failures are the harness rather than the server.

for a senior

Demonstrate the diagnosis order: read jmeter.log for the interrupt line, check whether the failures cluster at one instant, then size a trailing pause from the observed iteration duration.

for a principal

Own the standing rule for your plans — every open-model schedule ends with a pause, sized from measured iteration duration and revisited whenever the iteration grows, so results are never quietly truncated.

## What actually ends the run An Open Model Thread Group runs a starter task alongside the workload. The starter walks the schedule, sleeps until each scheduled arrival instant and submits a thread for it. When the generator has no events left, the starter computes how much of the schedule's total duration remains, sleeps out that remainder, and then shuts everything down. Shutdown is not polite. The manual puts it plainly: the thread group terminates threads as soon as the schedule ends — the threads are interrupted after all arrivals and pause intervals. Each surviving thread is asked to stop, then interrupted, and its task cancelled. A sampler that implements `Interruptible` has its in-flight work cancelled at that point, which is why the last samples of the run are failures with truncated durations rather than the successes you would get if they had been left alone. ## The log tells you this happened The thread group logs both outcomes. When nothing is left running it says it will shut the pool down. When threads are still live it prints the count and the remedy: > Test schedule finished, however, there are 37 thread(s) still running. Will interrupt the threads. If you want to keep some time for the threads to complete, consider adding pause(10 min) at the end of the schedule. So the first diagnostic step for a tail of failed samples is not the result file at all — it is `jmeter.log`. If that line is present, the failures are the harness cutting its own run short, not the system under test misbehaving. Reading the failures as a real defect is the classic misdiagnosis here. ## Why a trailing pause is the fix A pause step occupies duration without scheduling arrivals, and it is honoured in full even when nothing is left to do. Adding one at the end therefore extends the moment at which the starter gives up, and every thread that finishes inside that window completes normally. A hold-then-pause profile with headroom looks like this: - `rate(50/sec) random_arrivals(10 min)` — the load you actually wanted, - `pause(2 min)` — a deliberate quiet stretch inside the profile, - `random_arrivals(10 min)` — the same fifty per second again, - `pause(5 min)` — headroom, so the arrivals issued at minute twenty-two are not cut off. Note which steps do **not** buy you time: 1. A trailing `rate(0)` adds nothing — a rate step is a level and occupies no duration at all. 2. Setting Random Seed changes where arrivals fall inside a span, never how long the schedule lasts. 3. Lengthening the last `random_arrivals` span does extend the run, but it also keeps generating load, which is not what you asked for. ## Sizing the trailing pause The pause has to cover the slowest iteration that can still be in flight when the last arrival is issued, so the input is your own observed iteration duration from a previous run, not a round number. Two practical habits: - Keep the pause in the schedule text rather than in a comment or a wiki page, so it travels with the plan. - Re-check it after adding steps to the iteration; a plan whose iteration grew from two seconds to thirty will start truncating again with the old pause. ## What this is not This behaviour belongs to the Open Model Thread Group specifically — it is a property of *this* element's starter, not something you configure with an error action or a scheduler checkbox. There is no field on the element to soften it, and `bin/jmeter.properties` carries no key naming this thread group at all; the schedule text is the only lever. That is also why the truncated tail is so easy to misread: nothing in the GUI warns you, and the only signal outside the log is a cluster of failures whose durations stop dead at the same instant.

  • Would adding rate(0) to the end of the schedule give running threads more time?
    No. A rate step is a level, not a span: it names a rate at a point in the schedule and contributes no duration, so the total is unchanged and the starter still gives up at the same instant. Only an arrivals or pause span moves the end of the schedule.
  • How do you tell an interrupted tail from a genuine timeout in the system under test?
    The interrupted samples all stop at the same instant, at the end of the schedule, and jmeter.log carries the thread group's line naming how many threads it interrupted. A genuine timeout is spread across the run and matches the sampler's configured timeout instead.

saying these in an interview costs you the question

  • Blames the system under test for the tail failures
  • Adds a trailing rate(0) expecting it to add time
  • Thinks the group waits for running threads
  • Looks for a property to change the shutdown
  • Confuses the truncated tail with a real timeout