View all services
Talk to QA Advisor
Free tool · Performance and metrics

Load test calculator for users and throughput

Turn orders a day or page views an hour into the throughput, concurrent users and pacing a load test needs. Little's Law does the maths, every step is shown, and the result comes out as settings for k6, JMeter and Gatling.

Load test calculator

Turn business volumes and response times into load test targets: users, throughput and pacing, with the working and ready-to-paste k6, JMeter and Gatling settings.

Examples
Calculate

Start from business volume, such as orders a day, and work out the load to generate.

Business volume

Peak-hour share comes from analytics: the busiest hour divided by the day. The peak factor covers the busiest minutes inside the hour; use 1 if traffic is even.

Script

3.75 transactions per second, 187 virtual users.

Load to generate at peak

Every step of the arithmetic is shown below, so you can check it and explain it.

3.75/s

Transactions

13,500 an hour

45/s

Requests

2,700 a minute

187

Virtual users

Closed model, no pacing

49.8 s

Per transaction

Requests plus think time

How the result was calculated, step by step
StepWorkingResult
Peak-hour volume50,000 a day × 15%7,500 an hour
Peak-hour average rate7,500 ÷ 3,600 s2.0833 per s
Peak within the hour2.0833 × 1.5 peak factor3.125 per s
With safety margin3.125 × 1.23.75 per s
Request rate3.75 transactions per s × 12 requests45 requests per s
Time for one iteration12 × 0.4 s + 45 s think49.8 s
Virtual users (Little's Law)3.75 per s × 49.8 s186.75, so 187 users

Test configuration

The result above as settings for your load testing tool. Replace the sample request with your own script.

Open model: k6 starts iterations at the target rate whatever the response times, and records dropped_iterations if it runs out of VUs. constant-arrival-rate has no ramp-up; use ramping-arrival-rate with stages if you need one.

preAllocatedVUs follows the k6 sizing rule, rate × iteration time, plus 20% for variance: 3.75/s × 49.8 s × 1.2, rounded up = 225.

k6 arrival rate
import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  scenarios: {
    peak_load: {
      executor: 'constant-arrival-rate',
      rate: 225, // iterations started per timeUnit
      timeUnit: '1m',
      duration: '30m',
      preAllocatedVUs: 225, // rate × iteration time + 20%
      maxVUs: 450, // optional: extra VUs start mid-test only if the pre-allocated ones run out
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<500'],
  },
};

export default function () {
  // One business transaction: 12 requests
  http.get('https://test.example.com/');
  sleep(45); // think time
}
Ready
How to use

How to use the Load test calculator

  1. 1Choose what you know. Start from business volume with the workload model, solve for users, throughput or response time with Little's Law, or work out pacing for a fixed number of users.
  2. 2Enter the figures with their units. For a workload model, take the peak-hour share and requests per transaction from analytics or server logs, and an expected response time from a previous run or the target.
  3. 3Read the result and the working underneath it. In pacing mode, a warning shows when one iteration takes longer than the pacing interval, which means the target cannot be reached.
  4. 4Set the test duration, ramp-up and p95 threshold, choose k6, JMeter or Gatling, and copy the configuration into your test.

Little's Law, with a worked example

Little's Law says that the average number of items in a system equals the rate they arrive multiplied by the average time each one spends there. It holds for any stable system over a long enough period, whatever the distribution of arrivals or response times, which is why it is the starting point for sizing a load test.

For a load test, the items are virtual users and the time in the system is a whole user cycle: the response time plus the think time before the next action. An API with a target of 250 requests per second and a 180 ms response time, called by clients that send the next request straight away, has 250 × 0.18 = 45 requests in progress at any moment, so 45 virtual users can produce that load. A web journey with 100 users, a 0.5 s response time and 10 s of think time produces 100 ÷ 10.5 = 9.52 transactions per second.

  • Little's Law

    L = λ × W

    Items in the system = arrival rate × time each item spends in the system.

  • For a closed load test

    users = throughput × (response time + think time)

    Rearranged, throughput = users ÷ (response time + think time), and response time = users ÷ throughput − think time.

Think time and pacing

Think time is the pause a real user takes between actions: reading a page, filling in a form. It sits inside each iteration, so it lengthens the user cycle and lowers the throughput each virtual user generates. Leave it out and every virtual user behaves like a client in a tight loop, which makes the user count in the test meaningless as a measure of real users.

Pacing fixes the interval between the start of one iteration and the start of the next, whatever the response time. It is how a closed test holds a steady rate: with 200 users and a target of 100 iterations a second, each user starts one iteration every 2 seconds. Pacing only works while an iteration finishes inside the interval. Once response time plus think time exceeds it, users start late and throughput falls below the target.

  • Pacing interval

    pacing = users ÷ target iterations per second

    The interval each user must keep between iteration starts.

  • Fewest users that can reach the target

    users = target rate × (requests × response time + think time)

    With fewer users than this, no pacing value can reach the target.

Gatling pacing
forever().on(
  pace(Duration.ofSeconds(2)).exec(/* your requests */)
)
k6 pacing in a ramping-vus test
export default function () {
  const start = Date.now();
  // your requests
  sleep(Math.max(0, 2 - (Date.now() - start) / 1000));
}

From business volume to test targets

Stakeholders speak in orders a day or visitors a month. A load test needs requests per second and users. The conversion takes five steps, and each one should be written down so the target can be challenged and revised. Here is the e-commerce example the calculator opens on.

  1. 1

    Find the peak hour

    50,000 orders a day × 15% = 7,500 orders in the peak hour

    Use analytics or logs for the busiest hour of the busiest day, not the daily average.

  2. 2

    Convert to a rate

    7,500 ÷ 3,600 s = 2.083 orders per second

    This is the average rate across the peak hour.

  3. 3

    Allow for peaks within the hour

    2.083 × 1.5 peak factor × 1.2 safety margin = 3.75 orders per second

    Traffic is never even within an hour. A peak factor covers the busiest minutes, and a margin covers growth and campaigns.

  4. 4

    Convert to requests

    3.75 × 12 requests per order = 45 requests per second

    Count the requests the script actually sends for one transaction, including API calls behind the page.

  5. 5

    Size the users

    3.75 × (12 × 0.4 s + 45 s think time) = 186.75, so 187 users

    Little's Law with the full iteration time gives the users needed in a closed model.

Open and closed workload models

In a closed model, a fixed number of virtual users loop through the script, and each one starts its next iteration only when the last has finished. In an open model, new iterations arrive at a set rate, independently of whether earlier ones have finished. k6 offers both through its executors: ramping-vus and constant-vus are closed, constant-arrival-rate and ramping-arrival-rate are open. Gatling separates them as injectOpen and injectClosed.

The difference shows when the system slows down. In a closed model, slower responses mean longer iterations, so fewer new requests arrive and the load eases off just as the system struggles. The k6 documentation notes that this is known in some testing literature as coordinated omission. An open model keeps sending requests at the target rate, the way independent visitors to a public website do, so queues and response times grow as they would in production. Use an open model for public sites and APIs, and a closed model where the number of users really is fixed, such as an internal system with a known number of staff.

Checking the result in the test run

A calculated target is a hypothesis. When the test runs, compare the throughput actually achieved with the target. If throughput falls short while response times rise, the system is saturated, or the test does not have enough users. In k6 arrival-rate tests, a dropped_iterations count above zero means k6 ran out of VUs and could not start every iteration. The JMeter Constant Throughput Timer only adds pauses, so it cannot lift throughput above what the threads can deliver.

Little's Law also works as a check on the measurements: achieved throughput multiplied by the measured cycle time should come close to the number of active users. A large gap points to errors that return quickly, think time that is not what the script intends, or a load generator that has itself become the bottleneck. Judge response times by percentiles such as p95 and p99 rather than the average, and check that enough requests were collected for the percentile to be reliable.

QAble service

Performance testing

QAble builds workload models from your real traffic, scripts them in k6, JMeter or Gatling, and runs load, stress and soak tests that show where and why the system slows down.

Explore the service
FAQ

Frequently asked questions

How many virtual users do I need for a load test?

Multiply the target throughput by the time one user takes to complete an iteration, including think time. For 3.75 transactions a second and an iteration of 49.8 seconds, that is 186.75, so 187 users. In an arrival-rate test the tool works out the users itself, but you still need to pre-allocate roughly that number.

What is the difference between throughput and concurrent users?

Throughput is how much work is done per unit of time, such as requests per second. Concurrent users is how many users are active at once. They are linked by the time each user spends per cycle: the same throughput can come from a few users with no think time or many users who pause between actions, and those two tests load the system differently.

How do I set the JMeter Constant Throughput Timer?

The target is in samples per minute, so multiply requests per second by 60: 45 requests a second is 2,700 samples a minute. A timer applies to every sampler in its scope, so place it at thread group level when the target covers all requests. The JMeter documentation says the shared calculation modes should give a more accurate overall rate.

Why does my test not reach the target throughput?

Usually because there are not enough virtual users for the response times the system is producing. Each user can only complete one iteration per cycle, so when response times grow, a closed test slows down with them. Add users, reduce think time, or switch to an arrival-rate test. Also check the load generator itself for CPU or network limits.

Should think time be included in a load test?

Yes, for tests that model people using a website or app. Without think time each virtual user generates far more load than a real user, so the user count no longer means anything. Take think time from analytics or session logs where you can. For machine-to-machine APIs, think time is usually zero.

Is anything I enter sent to a server?

No. All calculations run in your browser, and nothing you type is sent anywhere.

Need a load test built on your real traffic?

QAble performance testers turn your analytics into a workload model, run it at peak and beyond, and trace the bottleneck behind every slow percentile.

Talk to QA Advisor