How Long Should a Load Test Run?

A standard load test should hold its target load for at least 10 to 15 minutes after a warm-up of 2 to 5 minutes, which you exclude from the results. Smoke tests need 1 to 2 minutes, stress and spike tests 10 to 30 minutes in total, and soak tests run for hours. The real floor is statistical: to report a stable p99 you want at least 10,000 samples from the steady-state window, so duration depends on your request rate as much as on the test type.
Recommended duration by test type
These are starting points that work for most web apps and APIs. Each row assumes you discard the warm-up and only report the steady window.
| Test type | Ramp-up | Steady / hold | Typical total | What the duration has to cover |
|---|---|---|---|---|
| Smoke | 0-10 s | 30-90 s | 1-2 min | Script works, auth works, no 4xx/5xx at trivial load |
| CI regression check | 30-60 s | 3-5 min | 4-6 min | Enough samples for a stable p95 to compare against a baseline |
| Load (expected peak) | 2-5 min | 10-30 min | 15-35 min | Warm caches, autoscaling settled, several GC and pool-recycle cycles |
| Stress / step | steps of 3-5 min | until the knee | 15-40 min | Each step long enough to reach steady state before the next one |
| Spike | 5-30 s | 2-5 min at peak | 10-20 min | The spike itself plus 5-10 min of recovery at normal load |
| Soak / endurance | 5-10 min | 2-12 h (or more) | hours | At least 2-3 cycles of the slowest periodic process (cron, TTL, token expiry) |
If you are unsure which type you need, the test-type overview in the load test plan template maps goals to test types. This page is about the clock.
Warm-up: why the first minutes do not count
The first minutes of any test measure a system that is not in its normal state. Things that change during warm-up:
- Connection setup. Every new VU opens TCP and TLS connections. Your load balancer, app server pools and database pools all grow from their idle size.
- Caches. Application caches, the database buffer pool and CDN edges start cold. Hit ratio climbs over minutes, not seconds.
- JIT and runtime. The JVM, V8 and .NET compile hot paths after they run enough times. Early requests run slower code.
- Autoscaling. If the target load needs more pods or instances, the first few minutes show the system before they exist. That is a valid thing to measure, but it is a different question (see autoscaling too slow).
Practical rule: exclude the ramp plus the first 1-2 minutes at target load, or until the steady-state check below passes, whichever is later. If your tool only gives whole-run summaries, run a separate short warm-up test first, then start the measured run immediately afterward. How fast to climb to the target is its own topic, covered in ramp-up period.
How many samples you need for a stable p95 or p99
A percentile is estimated from the slowest few samples. The p99 of 1,000 requests is decided by the 10 slowest, so one GC pause moves it. The quantity that matters is how many samples land above the percentile:
samples above pXX = n × (1 − XX/100)
n = RPS × steady-state seconds
A workable rule is to have at least 100 samples above the percentile you report. That gives n ≥ 2,000 for p95, n ≥ 10,000 for p99 and n ≥ 100,000 for p99.9.
How tight the estimate is
The number of samples above the true p99 follows a binomial distribution. With n = 10,000 you expect 100 of them, with a standard deviation of √(10,000 × 0.01 × 0.99) ≈ 10. A 95% interval is roughly 100 ± 20, so your measured "p99" is really somewhere between the true p98.8 and p99.2. That is good enough to compare runs. With n = 1,000 the interval is 10 ± 6 samples, which spans roughly p98.4 to p99.6. On a long-tailed distribution that can be a 2x difference in milliseconds.
Worked example: minimum steady time
| Steady RPS | Time for 2,000 samples (p95) | Time for 10,000 samples (p99) | Time for 100,000 samples (p99.9) |
|---|---|---|---|
| 20 | 100 s | 8.3 min | 83 min |
| 50 | 40 s | 3.3 min | 33 min |
| 200 | 10 s | 50 s | 8.3 min |
| 1,000 | 2 s | 10 s | 100 s |
The statistical floor is short at high RPS, but the warm-up and periodic-behavior arguments still apply, so a 10-minute steady window remains the sensible minimum for a load test that gates a release. Low-traffic endpoints are the opposite case: a checkout flow tested at 20 RPS needs over 8 minutes of steady time before its p99 means anything. The latency percentile calculator shows the same effect with your own samples, and p95 vs p99 covers which one to report.
A live chart that plots p99 per 10-second bucket at 100 RPS computes each point from 1,000 samples, so each point is decided by 10 requests. Expect jagged per-bucket p99 lines and judge the trend, not single points.
How to tell when you have reached steady state
Steady state means throughput, latency and resource usage have stopped trending. A simple test you can apply by eye or in a script:
- Split the run into 1-minute windows.
- For each window compute throughput, p95 and error rate.
- Steady state starts at the first window where the next three windows each stay within ±5% of it on throughput and ±10% on p95, with no upward trend.
Two cross-checks catch the cases where the numbers look flat but the system is not:
- Little's Law holds. In VU mode, concurrency ≈ throughput × (response time + think time). If the measured values disagree by more than ~10%, requests are queueing somewhere you are not measuring. See Little's Law for load testing.
- Resource metrics are flat. Heap after GC, DB connections in use, queue depth and pod count should level off. A p95 that is flat while heap after GC climbs means you are in a soak problem, not a steady state.
If steady state never arrives at your target load, that is the result: the system cannot sustain it. Report that instead of averaging a drifting run. Inconsistent load test results covers the common causes when two runs of the same test disagree.
Soak tests: matching duration to periodic behavior
A soak test exists to catch problems that only appear with time: memory leaks, slow connection leaks, disk filling with logs, and periodic jobs that collide with load. Its length is set by the slowest cycle in your system, not by a round number. Inventory the periodic processes and run for at least two or three of the longest one:
- Cache TTLs (a 1-hour TTL means the first mass expiry happens at minute 60).
- Connection lifetimes. HikariCP's default
maxLifetimeis 30 minutes, so a 20-minute test never sees a pool recycle. - Auth token expiry (1-hour access tokens are common), so a test with a single login per VU starts failing at minute 60.
- Cron jobs, backups, log rotation and batch imports, often hourly or nightly.
- Memory growth. If heap grows 30 MB per hour toward a 2 GB limit with 1.2 GB in use, the crash is about 27 hours away. Measure the slope over a few hours and extrapolate rather than waiting for it.
The memory leak soak test page shows how to read heap and RSS trends during a soak.
Fitting durations to LoadTester plan limits
LoadTester caps the duration of a single test per plan. Here is what each limit is honestly good for:
| Plan | Max duration | Max load | Good for | Not enough for |
|---|---|---|---|---|
| Free ($0) | 1 min | 10 VUs / 50 RPS | Smoke tests, script validation, a quick p95 at low RPS (3,000 samples at 50 RPS) | A stable p99, warm-up exclusion, any load test that gates a release |
| Starter ($19) | 5 min | 250 VUs / 500 RPS | CI regression checks: 1 min ramp + 4 min steady = up to 120,000 samples at 500 RPS | Full load tests with long warm-up, step stress tests with many levels |
| Pro ($49) | 20 min | 2,000 VUs / 2,000 RPS | Full load tests (3-5 min warm-up + 15 min steady), spike tests with recovery, 4-5 step stress tests | Multi-hour soak tests |
For soaks there are two honest options. First, a scheduled test (cron, available on Starter and Pro) can run, for example, a 20-minute test every hour and compare each run against a baseline. That catches drift across hours and days, such as a slowly degrading p95 or a nightly job that hurts latency. It does not reproduce continuous pressure, because load stops between runs and a leak that needs uninterrupted traffic may not show. Second, for a true 8-hour or 24-hour continuous soak, run k6, Locust, JMeter or Gatling on infrastructure you control; those tools have no duration cap and are the right choice for that job. The soak testing page compares approaches.
Common duration mistakes
- Reporting the whole run. Summary percentiles that include ramp-up mix two different systems. Report the steady window only, or keep the ramp short relative to the hold.
- Comparing runs of different lengths. A 5-minute run and a 20-minute run have different sample counts and see different periodic events. Keep CI regression runs identical in duration.
- Stopping at the first good minute. A 60-second test that looks clean says nothing about minute 12, when the connection pool fills or the autoscaler overshoots.
- Running a soak at peak load. A soak should run at realistic sustained load (often 60-80% of peak). At peak, you are running a long stress test and will hit capacity limits before slow leaks show.
- Ignoring recovery. Spike and stress tests should keep running at normal load after the peak. Time to recover to baseline p95 is often the most useful number they produce.
Duration checklist
- Pick the test type and start from the table above.
- Compute the steady-state seconds needed: 10,000 / RPS for p99, 2,000 / RPS for p95. Use the larger of that and 10 minutes for a release-gating load test.
- Add the ramp plus 1-2 minutes of warm-up, and mark that window as excluded.
- List periodic processes (TTL, pool lifetime, token expiry, cron). For a soak, run at least two cycles of the longest.
- Add recovery time after any spike or stress peak.
- Check the total against your tool's cap. If it does not fit, split into a scheduled series or use a self-run tool for that test.
FAQ
Is a 1-minute load test useful?
Yes, as a smoke test: it proves the script, auth and endpoints work and gives a rough p95 at low load. It is too short to exclude warm-up, see steady state or produce a stable p99 unless your request rate is high. Do not use it to approve a release.
Should I include the ramp-up in my results?
Not in the pass/fail percentiles. The ramp measures a system with cold caches, growing pools and possibly missing instances, which mixes a different question into your summary. Keep ramp data for diagnosing autoscaling and warm-up behavior, and judge the release on the steady window.
How many requests do I need for an accurate p99?
Aim for at least 10,000 samples in the steady window, so about 100 land above the p99. At that size the estimate typically falls between the true p98.8 and p99.2. For p99.9 you need about 100,000 samples.
How long should a soak test run?
Long enough to cover two or three cycles of your slowest periodic process, such as a 1-hour cache TTL, a 30-minute pool lifetime or nightly jobs. In practice that is 2 to 12 hours, and sometimes 24 hours or more for memory leaks. Run it at realistic sustained load, not peak.
Do longer tests give more accurate results?
Only up to a point. Once you have enough steady-state samples and have covered the periodic behavior you care about, extra time mostly adds cost. What improves accuracy after that is consistency: identical duration, data and environment across runs you compare.