Load testing with Apache JMeter

There are several ways to test the performance of a web application. In this article I want to discuss about how we can use Apache JMeter to do that. I’ll start with a basic use. And in the end of the article, I’ll discuss about how we can use JMeter to do a concurrent users stress test.

Write a basic test

There are two ways we can use JMeter:

  1. Graphical user interface
  2. Command line interface

It is recommended that we run actual test on CLI. But we can write a test & have a test-run on the GUI. Start the GUI by running this command:

$ apache-jmeter-5.4.1/bin/jmeter
Apache JMeter GUI

In this scenario, we are going to write a basic performance test targeting randomcolour.com, a very simple website.

I’ll rename the test plan as “Load testing randomcolour.com”.

Thread group

Next, let’s add a thread group on our test plan. Thread group determines user flow and how a user would behave. Each thread represent a user.

Add a thread group

In this thread group, I am adding 5 users (threads), ramp all users in 5 seconds (thus 1 second after each other). And I’ll only be running the test once (loop count = 1).

Thread configuration

Sampler

We want the thread to send an HTTP request. To do this we can add a “Sampler” to the thread group.

Add a sampler

In this sampler, I’m sending a request to randomcolour.com, using an http protocol.

Sampler configuration

As you can see, we can configure many parameters on this screen. We can simulate a POST request, simulate form filling action, file uploads, etc. But in this example I’m just going to request a simple HTTP request.

Timer

We can simulate the pause/delay when users click a website by adding a “Constant Timer”. Let’s add a timer to the HTTP request we’ve just created.

Add a timer

I’m going to use the default value of 300ms.

Listener

To see the result of our test on the GUI, we can add a “Listener”. In this example, I’m adding a “View Results Tree” listener to the thread group.

Add a listener

Run test on GUI

Remember, you should always run the test on JMeter CLI interface. But we can do a test-run on the plan we’ve just created. First we need to save it as a .jmx file. In this example, I name the file test-randomcolour.jmx.

To start a test, click the “Start” button on the top toolbar.

Here is the result of our test as shown in the “View Results Tree” screen.

The test result on JMeter GUI

Run test on CLI

To run the test on CLI, we can just use the .jmx file created using the GUI. Use the parameter -n to tell JMeter to run in non-GUI mode. Use the parameter -t to specifies the file to use for the test*.

*in this example, I store my .jmx files in the configs/ directory

$ apache-jmeter-5.4.1/bin/jmeter -n -t configs/test-randomcolour.jmx

Below is a screenshot of the test result. As you can see, JMeter returns the summary of the test which it runs on port 4445.

The test results on JMeter CLI

Concurrency load test

We can also do concurrency load test where we simulate multiple users (threads) accessing a website simultaneously. JMeter doesn’t have a default module for this, but luckily it supports plugins.

Installing JMeter plugin manager

You can find the JMeter Plugins Manager here. Simply download the JAR file, then copy it to JMeter’s lib/ext/ directory.

Open or restart JMeter GUI.

You can find the “Plugins Manager” on the “Options” menu and on the right of the top menubar.

Installing Concurrency Thread Group plugin

  1. Open the “Plugins Manager” on the GUI
  2. Click on the “Available Plugins” tab
  3. On the search bar, type in “Custom Thread Groups”
  4. Select it and click the “Apply Changes and Restart JMeter” button
Custom Thread Groups plugin

Write a concurrent load test

Open the JMeter GUI to create a new test. Then, add a concurrency thread group.

Add a Concurrency Thread Group

In this test I am going to simulate 100 concurrent users (threads). We’ll load all users within 1 minute in 10 increments (thus 10 users per 6 seconds). Once all 100 threads are added, we hold the connection for at least 1 minute*.

*we can manually stop the connection after 1 minute.

Concurrency thread group configuration

Next, we add the sampler, an HTTP request. We use a similar configuration as before: sending a request to randomcolour.com, using an http protocol.

For this test, I won’t be adding a listener (more on that later). For the final step, we save the test as a .jmx file. I name my test file as: test-randomcolour-ccu.jmx.

Run the concurrent test

We run the test using CLI. But this time, we want to save the result as a CSV file. We can open the CSV file on a spreadsheet application to check the result. But more importantly, we can create a summary report using JMeter afterwards.

Run the CLI command to run the test and create a report, add the parameter -l to indicate where we want to save the report file*.

*in this example, I save the report file as test-randomcolour-ccu.csv in the results/ directory.

$ apache-jmeter-5.4.1/bin/jmeter ⏎
-n -t configs/test-randomcolour-ccu.jmx ⏎
-l results/test-randomcolour-ccu.csv

Below is a screenshot of the test result and CSV file.

Concurrency thread group test result
Concurrency thread group test result CSV file

Note: we can manually stop the test from another terminal by running this command:

$ apache-jmeter-5.4.1/bin/stoptest.sh

Create a summary report

Using the CSV file created during the test we can make a summary report on JMeter GUI.

On the default test plan, add the listener “Summary Report”. We don’t have to create a thread group or a sampler, because we are going to read the CSV file to generate the report. Click the “Browse…” button and select results/test-randomcolour-ccu.csv.

Summary generated from the report file

How to read the summary report

This is the description about the columns in the summary report:

  1. Samples: total number of requests sent to the server during the duration of the test
  2. Average: sum of all the sample times divided by total number of requests
  3. Min: minimum time taken for the request to be completed (ms)
  4. Max: maximum time taken for the request to be completed (ms)
  5. Std. Dev.: Standard deviation of the response time average value
  6. Error %: percentage of failed tests
  7. Throughput: number of requests processed by the server per unit time
  8. Received KB/sec: self explanatory
  9. Sent KB/sec: self explanatory
  10. Avg. Bytes: average response size

Conclusion

There are many other scenarios on how we can use Apache JMeter to test the performance of our website. We can simulate user behaviour, run several thread groups, etc. This article should help you getting a basic understanding on how to start using JMeter. It is a very useful tool to have in your development process, especially if you want to know the performance and scalability of your website.

If you have any question or suggestion, give me a nudge on Twitter. Cheers!

Additional reading

  1. Getting Started with JMeter — A Basic Tutorial
  2. Load Testing using Concurrency Thread Group in Apache JMeter
  3. JMeter Result Analysis: The Ultimate Guide

Programmer