Load Testing for Beginners: Tools, Concepts, and Examples

A website or application may work perfectly when one person is using it—but what happens when 1,000, 10,000, or even 100,000 people try to use it at the same time?
Pages may begin loading slowly. Requests may time out. Databases may struggle to keep up. In extreme cases, the application may stop responding entirely.
This is where load testing becomes important.
Load testing helps software testers determine how an application behaves when it is subjected to the amount of traffic it is expected to receive in the real world.
In this beginner’s guide, we will cover:
- What load testing is
- Why it is important
- Load testing vs. stress testing and other performance tests
- Key load-testing concepts and metrics
- Popular load-testing tools
- Beginner examples using JMeter and k6
- How to interpret results
- Common mistakes to avoid
What Is Load Testing?
Load testing is a type of performance testing that evaluates how a system behaves when multiple users or processes use it at the same time.
Instead of checking only whether a feature works, load testing asks questions such as:
- Can the application support 500 concurrent users?
- How quickly do pages respond under heavy traffic?
- Does performance become slower as more users are added?
- Does the server begin producing errors?
- Can the system process the required number of transactions?
- Does performance recover after traffic decreases?
Consider an online shopping website.
A functional test might verify that a customer can:
- Open the website.
- Search for a product.
- Add the product to a shopping cart.
- Enter shipping information.
- Complete the purchase.
A load test might simulate 500 customers performing these activities at approximately the same time.
The goal is no longer simply to determine whether checkout works. The goal is to determine whether it continues working quickly and reliably when many customers are using it.
Why Is Load Testing Important?
Performance problems are sometimes invisible during normal functional testing.
Suppose a tester opens a login page, enters a username and password, and selects Login.
The system responds in 0.7 seconds.
Everything appears fine.
Now imagine 2,000 employees arrive at work and attempt to log in during the same five-minute period.
Suddenly:
- Login takes 10 seconds.
- Some requests time out.
- CPU utilization reaches 100%.
- Database connections become exhausted.
- Some users receive HTTP 500 errors.
The login feature itself may be functionally correct. The problem is that the application cannot handle the required workload.
Load testing can help discover these problems before real users encounter them in production.
Load Testing vs. Performance Testing
Performance testing is the broader category of testing that evaluates system speed, responsiveness, stability, and scalability.
Load testing is one type of performance testing.
| Test Type | Main Question |
|---|---|
| Load testing | Can the system handle the expected workload? |
| Stress testing | What happens when the system is pushed beyond expected capacity? |
| Spike testing | What happens when traffic suddenly increases? |
| Endurance testing | Can the system maintain performance for a long period? |
| Scalability testing | How does performance change as workload or resources increase? |
| Volume testing | How does the system behave with large amounts of data? |
Load Testing vs. Stress Testing
Suppose a company expects a maximum of about 1,000 concurrent users.
A load test might gradually increase traffic:
100 users
250 users
500 users
750 users
1,000 users
The objective is to verify that the application performs acceptably within its expected range.
A stress test might continue beyond that:
1,000 users
1,500 users
2,000 users
3,000 users
The objective is to discover the application’s breaking point and see how gracefully it fails.
Spike Testing
Spike testing evaluates sudden increases in traffic.
For example:
| Time | Users |
|---|---|
| 9:00 | 100 |
| 9:05 | 100 |
| 9:06 | 2,000 |
| 9:15 | 2,000 |
| 9:16 | 100 |
This is useful for applications such as:
- Ticket-sale websites
- Online registration systems
- Product launches
- News websites
- Black Friday sales
- Government application portals
Endurance Testing
Endurance testing, also called soak testing, checks whether a system can maintain acceptable performance for an extended period.
For example:
Run 500 users continuously for eight hours.
This can reveal problems such as:
- Memory leaks
- Database connection leaks
- Resource exhaustion
- Growing log files
- Cache problems
These problems may not appear during a short test.
Important Load-Testing Concepts
Before using a tool such as JMeter or k6, beginners should understand several basic concepts.
Virtual Users
A virtual user, often called a VU, represents a simulated user interacting with the system.
Instead of hiring 500 people to use a website at once, a load-testing tool generates requests representing those users.
For example:
100 virtual users repeatedly search for products for 10 minutes.
A good load test attempts to make these virtual users behave somewhat like real users.
Concurrent Users
Concurrent users are users interacting with the application during approximately the same period.
For example, an application may have:
5,000 users logged in
but only:
500 users actively sending requests
at a particular moment.
This distinction is important when designing realistic tests.
Requests
A request is an interaction sent to an application or server.
For a web application, requests may look like:
GET /products
GET /products/123
POST /login
POST /checkout
A single user action may generate several requests.
Requests per Second
Requests per second (RPS) measures how many requests a system processes each second.
For example:
1,200 requests in 60 seconds
1,200 / 60 = 20 requests per second
RPS is a useful throughput measurement, but it is not the same as the number of users.
One user may generate several requests.
Transactions
A transaction represents a meaningful business activity that may contain one or more requests.
Examples include:
- Logging in
- Searching
- Creating an account
- Submitting an application
- Completing a purchase
For example, checkout may generate several HTTP requests, but testers may still want to measure the performance of the entire Checkout transaction.
Response Time
Response time measures how long the system takes to respond.
For example:
GET /products
Response time: 420 milliseconds
Response time is one of the most important load-testing metrics.
However, beginners should avoid focusing only on averages.
Percentiles: p90, p95, and p99
Suppose a report says:
p95 response time = 1.8 seconds
This means approximately 95% of the measured requests completed within 1.8 seconds.
The remaining 5% took longer.
Common percentiles include:
p50
p90
p95
p99
For example:
Average: 0.9 seconds
p90: 1.3 seconds
p95: 1.8 seconds
p99: 4.7 seconds
This provides more useful information than the average alone.
Most users may receive fast responses while a small percentage experience serious delays.
Throughput
Throughput measures how much work the system completes within a period.
It may be measured as:
- Requests per second
- Transactions per second
- Transactions per minute
- Orders per minute
For example:
500 checkout transactions in 5 minutes
500 / 5 = 100 transactions per minute
Error Rate
The error rate measures the percentage of requests that fail.
Suppose a test generates:
10,000 requests
250 failures
The error rate is:
250 / 10,000 x 100 = 2.5%
Errors might include:
- HTTP 500 Internal Server Error
- HTTP 503 Service Unavailable
- Connection timeout
- Connection refused
- Incorrect application response
- Failed assertion
A system that responds quickly but returns errors is still failing.
Think Time
Real users do not continuously send requests.
They pause to:
- Read pages
- Enter information
- Compare products
- Complete forms
- Make decisions
A load test should often simulate these pauses.
This is called think time.
For example:
Open product page
↓
Wait 5 seconds
↓
Add product to cart
↓
Wait 10 seconds
↓
Open checkout
Without think time, a load test may generate much more traffic than real users would.
Ramp-Up and Ramp-Down
Instead of immediately launching hundreds of users, load tests often increase traffic gradually.
This is called ramp-up.
For example:
0 minutes: 0 users
1 minute: 20 users
2 minutes: 40 users
3 minutes: 60 users
4 minutes: 80 users
5 minutes: 100 users
Ramp-up can help identify the point at which performance begins to deteriorate.
Ramp-down is the opposite process, where traffic gradually decreases.
This can help determine whether the system recovers properly after heavy traffic.
Performance Requirements and Acceptance Criteria
A useful load test should have clearly defined pass/fail criteria.
For example:
The application shall support 500 concurrent users while maintaining a p95 response time below two seconds and an error rate below 1%.
The requirements are therefore:
Users: 500
p95 response time: < 2 seconds
Error rate: < 1%
Without acceptance criteria, a tester may collect large amounts of data without knowing whether the application actually passed.
Performance requirements should ideally come from business expectations, service-level targets, historical performance, or technical requirements rather than arbitrary numbers.
What Should You Monitor?
The load-testing tool provides important information, but it is also useful to monitor the infrastructure supporting the application.
Application metrics
- Response time
- Request rate
- Transaction rate
- Error rate
Server metrics
- CPU utilization
- Memory utilization
- Disk activity
- Network activity
Database metrics
- Query duration
- Database CPU
- Number of connections
- Connection pool usage
- Locks
- Slow queries
This information can help identify why performance becomes slow.
For example:
Users: 700
p95 response time: 6.2 seconds
Web server CPU: 42%
Database CPU: 99%
The database may be the bottleneck.
The team could then investigate:
- Slow SQL queries
- Missing indexes
- Locking
- Inefficient queries
- Connection limitations
Popular Load-Testing Tools
There are many performance-testing tools available.
Four common options are:
- Apache JMeter
- Grafana k6
- Locust
- Gatling
Apache JMeter
Apache JMeter is a popular open-source load-testing application.
Website:
https://jmeter.apache.org/
JMeter includes a graphical interface that allows testers to create test plans containing:
- Thread Groups
- HTTP Requests
- Timers
- Assertions
- Controllers
- Listeners
JMeter is often a good choice for beginners because basic tests can be created without much programming.
Grafana k6
Grafana k6 is a load-testing tool where test scenarios are commonly written using JavaScript.
Website:
https://k6.io/
k6 is useful when performance tests will be:
- Stored with source code
- Version controlled
- Automated
- Integrated into CI/CD pipelines
It is especially appealing to testers who are comfortable with basic JavaScript.
Locust
Locust allows testers to create load tests using Python.
Website:
https://locust.io/
It is a good choice for teams already working with Python.
Gatling
Gatling is another performance-testing platform that supports code-driven testing and automation.
Website:
https://gatling.io/
It can be particularly useful for development teams incorporating performance testing into automated pipelines.
Which Tool Should a Beginner Learn?
There is no single correct choice.
| Tool | Best Fit |
|---|---|
| JMeter | Beginners who prefer a graphical interface |
| k6 | Testers interested in JavaScript and test automation |
| Locust | Testers who already know Python |
| Gatling | Teams interested in code-driven performance testing |
For someone completely new to load testing, JMeter is a reasonable place to start.
For someone interested in automated testing and CI/CD, k6 is also worth learning.
Beginner JMeter Example
Imagine we want to test this fictional page:
https://example.test/products
Our requirements are:
Users: 50
Ramp-up: 60 seconds
p95 response time: < 2 seconds
Error rate: < 1%
Step 1: Create a Test Plan
Open JMeter and create a new Test Plan.
Give it a descriptive name such as:
Product Page Load Test
Step 2: Add a Thread Group
Right-click the Test Plan:
Add
→ Threads (Users)
→ Thread Group
Configure:
Number of Threads (Users): 50
Ramp-Up Period: 60 seconds
Loop Count: 10
This means:
- 50 simulated users
- Users introduced gradually over 60 seconds
- Each user repeats the scenario 10 times
Step 3: Add an HTTP Request
Right-click the Thread Group:
Add
→ Sampler
→ HTTP Request
Configure:
Protocol: https
Server Name: example.test
Method: GET
Path: /products
Step 4: Add Think Time
Add a timer:
Add
→ Timer
→ Constant Timer
For example:
Thread Delay: 3000 milliseconds
This creates a three-second pause between requests.
Step 5: Add an Assertion
Do not only verify that the server responded quickly.
Check that the response is correct.
For example, you could verify that the page contains:
Products
This prevents an error page from being counted as a successful response simply because it loaded quickly.
Step 6: Review Results
While creating the test, a listener such as View Results Tree can help inspect requests and responses.
For larger load tests, however, JMeter is generally better run from the command line because the graphical interface consumes additional resources.
A typical command is:
jmeter -n -t product-test.jmx -l results.jtl -e -o report
Simple k6 Example
A basic k6 load test might look like this:
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 10,
duration: '30s',
};
export default function () {
http.get('https://test.example.com/products');
sleep(2);
}
This tells k6 to:
- Simulate 10 virtual users
- Run for 30 seconds
- Request the products page
- Wait two seconds before repeating
We can also add performance thresholds:
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 20,
duration: '1m',
thresholds: {
http_req_failed: ['rate<0.01'],
http_req_duration: ['p(95)<2000'],
},
};
export default function () {
http.get('https://test.example.com/products');
sleep(2);
}
The thresholds mean:
Error rate < 1%
p95 response time < 2 seconds
This allows the test to automatically determine whether performance requirements were met.
Create Realistic User Journeys
A good load test should model realistic user behaviour.
For an online store, a scenario might look like:
Open homepage
↓
Wait 3 seconds
↓
Search for "headphones"
↓
Wait 5 seconds
↓
Open product
↓
Wait 10 seconds
↓
Add product to cart
↓
Open shopping cart
Real users may also perform different activities.
For example:
50% Browse products
25% Search
15% View cart
8% Begin checkout
2% Complete purchase
Different operations place different demands on the application.
Browsing a cached product page may use few resources, while checkout may involve:
- Authentication
- Database updates
- Inventory checks
- Payment processing
- Tax calculations
- Email notifications
The more closely the test represents real behaviour, the more useful the results become.
Example Load-Test Results
Suppose a test produces these results:
| Users | p95 Response Time | Error Rate |
|---|---|---|
| 100 | 0.8 sec | 0.0% |
| 250 | 1.1 sec | 0.1% |
| 500 | 1.7 sec | 0.3% |
| 750 | 3.9 sec | 1.8% |
| 1,000 | 8.2 sec | 7.4% |
Suppose the requirement is:
500 concurrent users
p95 < 2 seconds
Errors < 1%
The application passes at 500 users.
However, performance deteriorates substantially at 750 users.
This is useful information if traffic is expected to increase in the future.
Look for Performance Trends
Performance testing is often about identifying patterns rather than looking at one number.
Consider:
100 users → 0.8 seconds
300 users → 1.0 seconds
500 users → 1.3 seconds
600 users → 1.5 seconds
700 users → 4.7 seconds
800 users → 9.1 seconds
The important question is:
What changed between approximately 600 and 700 users?
Possibilities include:
- Database connection pool reached its limit
- CPU reached 100%
- Application queue became full
- Memory became exhausted
- A downstream service reached capacity
This is where load testing becomes an investigative activity rather than simply generating traffic.
Common Load-Testing Mistakes
1. Starting With Too Much Load
Do not immediately simulate 10,000 users.
Start small:
1 user
10 users
25 users
50 users
100 users
This makes performance problems easier to diagnose.
2. Forgetting Think Time
Virtual users that continuously send requests may generate unrealistic traffic.
3. Looking Only at Average Response Time
Always consider percentiles such as p95 and p99.
4. Ignoring Errors
A response time of 100 milliseconds is meaningless if 20% of requests fail.
5. Using Unrealistic Test Scenarios
Repeatedly requesting the homepage may not represent how real customers use the application.
6. Overloading the Load Generator
The computer running JMeter, k6, Locust, or Gatling also has limits.
If your load generator reaches 100% CPU, it may become the bottleneck instead of the application being tested.
7. Testing Without Requirements
A result such as:
Average response time: 1.4 seconds
means very little unless you know what was considered acceptable.
Define performance expectations before running the test.
Never Load Test a Website Without Permission
Beginners sometimes install a tool and experiment against a random public website.
Do not do this.
Heavy automated traffic can disrupt services and may violate the website owner’s policies.
Use:
- Your own application
- A local test application
- A dedicated test environment
- A system you have explicit permission to test
Load testing production systems should also be carefully planned because a poorly designed test could:
- Make the application unavailable
- Create thousands of records
- Send emails
- Trigger security systems
- Generate unexpected cloud costs
- Overload third-party services
Load Testing and Functional Testing
Load testing does not replace functional testing.
Suppose:
POST /api/orders
responds in:
120 milliseconds
That sounds excellent.
But what if the response is:
HTTP 500 Internal Server Error
The response is fast—but incorrect.
Performance tests should therefore include checks or assertions whenever possible.
A fast incorrect response is still a failed test.
Load Testing in CI/CD
Performance testing can also be incorporated into automated development pipelines.
For example:
Developer commits code
↓
Application builds
↓
Unit tests run
↓
API tests run
↓
Small performance test runs
↓
Deployment continues if thresholds pass
A team might automatically check:
p95 < 500 ms
Error rate < 1%
This can help identify performance regressions before software reaches production.
A Beginner Load-Testing Checklist
Before running a load test, ask:
Objective
- What am I trying to learn?
- How many users should the system support?
Workload
- How many virtual users should be simulated?
- Should users ramp up gradually?
- What activities should they perform?
- How long should the test run?
Requirements
- What response time is acceptable?
- What error rate is acceptable?
- What throughput is required?
Environment
- Am I authorized to test this system?
- Is the test environment appropriate?
- Could the test affect real users?
Monitoring
- Am I measuring response times?
- Am I monitoring errors?
- Can I monitor CPU and memory?
- Can I monitor the database?
Analysis
- When did performance begin to deteriorate?
- Which resource reached its limit?
- Did errors increase?
- Did the system recover when traffic decreased?
Final Thoughts
Load testing answers an important question that normal functional testing cannot:
Does the application continue to work properly when many users are using it at the same time?
For a beginner tester, the most important lesson is that load testing is not simply about generating as much traffic as possible.
A useful load test requires:
- A realistic workload
- Realistic user behaviour
- Appropriate think time
- Relevant performance metrics
- Defined acceptance criteria
- Infrastructure monitoring
- Careful analysis of the results
Tools such as Apache JMeter, Grafana k6, Locust, and Gatling can generate the workload, but the tester still needs to decide what realistic traffic looks like and what acceptable performance means.
Start small. Establish a baseline. Gradually increase the workload. Monitor response times, percentiles, throughput, errors, CPU, memory, and database behaviour.
Most importantly, do not simply ask:
“How many users can the system handle?”
A better question is:
“How many users can the system support while still meeting the required level of performance and reliability?”
That is the real purpose of load testing.
🗨️ Reader Comments