Key takeaways
- The ramp-up period is the number of seconds JMeter takes to start all the threads in a Thread Group. JMeter starts them evenly: the gap between two threads is ramp-up divided by thread count.
- The first thread starts at once, so the last one starts at (threads - 1) times that gap, a little before the ramp-up ends. With 100 threads and 50 seconds, a thread starts every 0.5 seconds and the last starts at 49.5 seconds.
- Ramp-up controls how fast threads start, not how many are active. If each thread finishes quickly, concurrency stays far below the thread count.
- A plain Thread Group ramps linearly. Stepped or multi-stage profiles need the Ultimate, Concurrency or Stepping Thread Group plugins.
The JMeter ramp-up period is a field in the Thread Group that sets how long JMeter takes to start all of its threads. Set it to 0 and every thread starts at the same moment, which produces a spike no real audience creates. Set it too long and the test ends before it ever reaches the load you meant to test. This guide gives the exact arithmetic, a run you can reproduce, and the settings that decide whether the ramp does what you expect. It is written against JMeter 5.6.3 (which needs Java 8 or newer).
What the JMeter ramp-up period does
The component reference defines it as how long JMeter should take to get all the threads started. Its own example: 10 threads and a ramp-up of 100 seconds means each thread begins 10 seconds after the previous one. It adds that the first thread always starts directly, so with one thread the ramp-up is effectively zero, and that the tenth thread in the example starts after 90 seconds, not 100 (Thread Group reference).
So the rule is:
gap between thread starts = ramp-up seconds / number of threads
start time of thread n = (n - 1) x gap
The old shortcut “100 threads, 100 seconds ramp-up is one thread per second” is correct as a rate. The detail to remember is that the last thread starts one gap before the end of the ramp-up.
A measured example: 100 threads over 50 seconds
I ran a Thread Group with 100 threads, a 50 second ramp-up and one loop against a local mock server, using JMeter 5.6.3 in non-GUI mode, and read the start times from the results file. The first request left at 0.0 s, the next at 0.41 s, 0.91 s, 1.41 s and 1.90 s, and the 100th at 49.4 s. Counting requests per whole second gave 2 or 3 in every second from 0 to 48 (3 in the first second because of the thread started at 0.0). That matches 2 threads per second and a last start at 49.5 s, within timing noise.
Now the part that surprises people. The same run reported Active: 1 in JMeter’s summary for most of the test, with 100 threads started and 100 finished by the end. Each request took about a millisecond and each thread had one loop, so every thread was done before the next one started. The ramp-up worked exactly as configured, yet the server never saw more than one user at a time.
To see ramp-up as concurrency, threads have to stay alive. I ran the same plan with an infinite loop, a 1 second constant timer between requests and a 70 second scheduler duration. The number of active threads in the results file was 55 at about 25 s, 85 at about 40 s and 100 from about 49 s until the end, which is the straight line the arithmetic predicts. Concurrency equals the ramp-up line only when each thread keeps running for the whole test.
Thread Group settings that interact with ramp-up
- Number of Threads (users): how many threads JMeter starts in total.
- Ramp-up period (seconds): the field this article is about.
- Loop Count: how many times each thread runs the plan, or infinite. With a small loop count and fast requests, threads finish during the ramp and the peak never reaches the thread count, as shown above.
- Specify Thread lifetime, Duration and Startup delay: the scheduler. The manual says that with the scheduler JMeter runs the group until the loop count is reached or the duration or end time is reached, whichever comes first. The check happens between samples, so a thread waiting on a slow response is not interrupted.
- Delay Thread creation until needed: if selected, threads are created only when the matching share of the ramp-up has passed. The manual recommends it when the ramp-up is much longer than the time to run one thread, so that early threads finish before later ones start. Otherwise JMeter creates all threads at the start and they wait.
A practical consequence for planning: the time you spend at full load is the test duration minus the ramp-up. A 5 minute test with a 4 minute ramp-up holds the target for about a minute. To make thread count and ramp-up configurable per run, put ${__P(threads,100)} and ${__P(ramp,50)} in the fields and pass -Jthreads=200 -Jramp=100 on the command line, as described in the parameterization guide.
How long should the ramp-up be?
There is no universal value. Three things set it:
- How traffic arrives. A newsletter or ad campaign sends people in a burst, so a short ramp is the realistic case. Steady organic traffic builds over many minutes, so a long one is. Copying a default matches neither.
- The warm-up the system needs. Caches, connection pools, JIT compilation and autoscaling groups all react to load over minutes. A ramp that is slower than they are shows you the system at steady state. A ramp that is faster shows you the transition.
- How you want to find the limit. To locate the point where response times or errors start to climb, ramp slowly and compare the load at the moment of the first degradation with the load you expected. With a very short ramp you learn only that the system cannot take the sudden start.
The Precise Throughput Timer section of the component reference warns of both ends: a ramp-up of 0 (or a very small number) starts all threads together and creates an unwanted spike, while one that is too high may leave too few threads at the beginning to reach the required load. When you need a constant arrival rate rather than a growing user count, the manual points to the Precise Throughput Timer and recommends setting both ramp-up and delay to 0 with it.
Stepped and staged ramp-ups need plugins
A standard Thread Group has one linear ramp. If you want to hold at 50 users, then jump to 100, then drop, you need a plugin thread group from the JMeter Plugins project, installed with the Plugins Manager (see how to install extra plugins in JMeter):
- Ultimate Thread Group: a table of records, each with a thread count, an initial delay, a startup time, a hold time and a shutdown time. Each record adds its own threads, so records combine into a custom profile.
- Concurrency Thread Group: you set a target concurrency, a ramp-up time, an optional number of ramp-up steps and a hold time. It starts new threads during the run when too few are active in parallel, and it does not create all threads upfront, so it uses less memory. It also lets threads finish their work gracefully when the load shrinks.
- Stepping Thread Group: adds threads in batches. Its own page says a probably better alternative is the Concurrency Thread Group.
None of these ship with JMeter itself. Build them in the GUI and save the plan rather than writing the XML by hand, because the element names belong to the plugin. For the thread groups that do ship with JMeter, including setUp, tearDown and the Open Model Thread Group, see our JMeter thread groups guide.
Ramp-up in LoadFocus
When you upload a .jmx file to LoadFocus per its JMeter load testing page, you set the virtual users, duration and ramp-up for the run in the browser. LoadFocus describes its ramp-up as the delay between the start of the test and the moment all virtual users are running, with a slider that previews the load profile, in its ramp-up time guide. The same reasoning applies there as in JMeter.
Troubleshooting a ramp-up that does not look right
- The peak is lower than the thread count. Threads finished before the ramp ended. Raise the loop count, use the scheduler duration, or add think time between requests. The virtual users guide explains why think time sets the ratio of users to requests per second.
- Errors appear in the first seconds only. Check ramp-up 0 first, then connection setup: new threads open connections, which costs time and resources.
- The client is the bottleneck. A single machine can only run so many threads before JMeter itself slows down, which distorts the ramp. See how many threads one machine can run and run in non-GUI mode (
jmeter -n -t plan.jmx -l results.jtl). - You need the number of concurrent users from analytics. Work it out first with the concurrent users calculator guide, then choose threads and ramp-up to reach it.
Frequently Asked Questions
What is the ramp-up period in JMeter?
It is the time in seconds that a Thread Group takes to start all of its threads. JMeter starts them at even intervals of ramp-up divided by thread count, beginning with the first thread immediately.
How do you calculate the ramp-up period?
Choose the ramp-up from how fast you want load to grow: threads divided by ramp-up gives threads started per second. For 100 threads over 50 seconds that is 2 per second. Pick the time first and let the rate follow, or pick the rate and compute the time (threads divided by rate).
What happens if the ramp-up period is 0?
All threads start at once. That is a spike test, not a gradual load, and it often shows errors that connection setup and cold caches cause rather than a real capacity limit.
How do I set the test duration in JMeter?
Select Specify Thread lifetime in the Thread Group and enter Duration in seconds, with an optional Startup delay. The group stops when the loop count or the duration is reached, whichever comes first. Set Loop Count to infinite if you want the duration alone to decide.
Can JMeter ramp up in steps?
Not with the standard Thread Group, which ramps linearly. The Ultimate, Concurrency and Stepping Thread Groups from the JMeter Plugins project add stepped and staged profiles.
Sources
- JMeter component reference, Thread Group, checked 2026-10-23 (JMeter 5.6.3).
- Ultimate Thread Group, Concurrency Thread Group and Stepping Thread Group, checked 2026-10-23.
- Run results: JMeter 5.6.3, non-GUI, local mock server, 2026-10-23.