A Simple Load Test with JMeter

Submitted by Gergely Lekli on Mon, 07/18/2011 - 9:45am
Gergely Lekli's picture

In connection with the recent launch of a high-profile Drupal-based website, one of my responsibilities was to evaluate how well the then un-launched system would perform under the expected load. As a web developer, I don't often have the opportunity to do load testing, so I had to do some research on the topic beforehand. This post is a summary of the steps I took and my findings.

The site had been in operation for quite some time, so we had existing statistics that helped us predict how many visitors the site would need to be able to serve. Using JMeter, I tried to replicate the load the server was likely to undergo.

Setting up JMeter

JMeter is a powerful open-source Java application with a wide variety of features, which makes it daunting to set up a test plan in it. While I was browsing for documentation on the topic, I found a sample JMeter plan specific for Drupal on Drupal Performance Testing Suite’s page. This plan comes with HTTP request, header, and listener elements set up. The following figure shows how the plan document looks.

 

The following are the few customizations one needs to do before using it:

  • Activate the User Defined Variable element corresponding to your Drupal version; deactivate the other.
  • Set host variable to the hostname of the server you wish to test.
  • In both thread groups, set the Number of Threads. This is the number concurrent users you wish to simulate.
  • In both thread groups, set the Loop Count. This number will determine how many times each thread is run, and therefore controls the length of the test. If you wish to get a picture of how the server performs under constant load, aim for minute-long tests. Second-long tests may not yield relevant results, because the server may need some time to stabilize under the changed load conditions – new server threads need to be created, for example. If you have a target time, and an approximate value for the throughput (the number of requests the server can handle in one second), you can calculate the Loop Count with this formula:
    Loop Count = Throughput * Time / Number of Threads.
  • Modify, add or delete HTTP request elements so that they reflect the pages that you wish to fetch with the request.
  • Keep-alive and Accept-Encoding headers may be adjusted in HTTP Header Manager elements, although it is typical to find keep-alive and compression enabled in most browsers, so leaving them intact should be fine.

After experimenting with it on Windows, I found that JMeter uses up a lot of memory, and will throw a java.lang.OutOfMemoryError: GC overhead limit exceeded error eventually. The problem can be mitigated by setting the memory limits in jmeter.bat. With the limit set to 512MB, it was able to run about 3100 requests. Although I did not go above this number, I still increased the memory limit so that it does not impact speed as it gets close to this number and fills up the memory.

Preparing data

In order to get an idea of how many concurrent users I should simulate, I examined the site statistics. The owner of the websites oranizes events, which tends to attract more visitors to the website than usual. For that reason, there are occasional spikes in server load, which is illustrated by the figure below.

 

Visitors between 5/1/2010 and 5/1/2011. Total visitors: 3,835,880

To get a sense of how the server handles increasing traffic, I wanted to run multiple tests with gradually increasing number of concurrent users. I chose the smallest number to start the test with to be the average number of concurrent visitors based on one month’s data. Of course this does not tell us much about the actual load at any given moment, but it gives a stress baseline that the sever is constantly subject to. The following figure shows the data that was used to calculate the average number of concurrent visitors.

 

Visitors between 4/1/2011 and 4/30/2011
Total visitors: 366,975
Total pageviews: 937,643
Avg. time on site: 87 sec

The data that are readily available to us in Google Analytics are the number of visitors and the average length of visit. From those numbers, one can calculate the number of concurrent users using the following formula:

Number of Concurrent Users = Rate of Incoming Visitors * Time of Visit

Because we have the length of visit in seconds, we also need to project the number of monthly visitors to seconds.

Rate of Incoming Visitors = 366,975 visitor / (30 days * 24 hours * 60 minutes * 60 seconds) = 0.1415 visitors / second

which gives

Number of Concurrent Users = (0.1415 visitor / second) * 87 seconds = 13 visitors

The second cycle of tests was based on the data corresponding to a recent peak. That showed traffic that the server would definitely encounter in the future. I chose the peak of 3/11, which is the largest peak in this year’s data. The figure below shows the hourly graph for visitors on 3/11.

Hourly graph for the peak of 3/11/2011.
Visitors at the peak of 9am: 1,570
Pageviews at the peak of 9am: 5,328
Avg. time on site: 108 sec

The number of visitors at the peak of 9am is 1570. Applying the previously used formula, we get

Rate of Incoming Visitors = 1,570 visitors / 60 minutes / 60 seconds = 0.4361 visitors / second

Number of Concurrent Users = (0. 4361 visitor / second) * 108 seconds = 48 visitors

Finally, in the third cycle of tests, I wanted to stay on the safe side, and come up with a number that surpasses any anticipated surge. It seemed reasonable to think that a load about twice as much as the largest peak so far would be an extreme event and unlikely during normal operation (or there would be some warning signs at least). Therefore I set the visitor parameter to 100 in the last round of tests.

That gave me 13, 48, and 100 in terms of concurrent visitors to test. Next I had to decide which pages I should run the tests against. Whatever I choose would have been unrealistic, because it is pretty unlikely that hundreds of visitors click through the same couple of pages. The best I thought I could do is run the tests against the pages that are visited the most frequently. That way, the test requests overlap a large portion of the real-life requests.

The most visited page on the site I am testing is the homepage, which contains multiple Drupal Views. There is another page that has many inbound links and is requested more often than all the other pages; I included that too. The third page I tested is a Drupal node page. Node pages are very similar in structure, and make up the vast majority of pages. I will refer to these pages as Homepage, Landing Page, and Node, respectively.

Running the tests

The load was generated on a separate computer in a network separate from the server. That way, the test results include every factor that comes into play when someone requests a page, including network latencies as well as page rendering times. Furthermore, if the load had been generated on the same machine that serves the pages, the load generator would have taken away some of the server’s resources, thus affecting the results.

During the tests, I monitored the server load, using the top command. I noted 1-minute average values read toward the end of the test. Because all the tests ran longer than 1 minute, all the data in the average are covered by the test load. The test results were acquired from the Summary Report element of the test plan. I ran the tests multiple times and took the results that I was able to reproduce.

Drupal page caching is enabled on the site. There is no open registration available; only employees of the organization have user accounts; the majority of the traffic comes from anonymous users.

The test results are as follows:

13 concurrent visitors, 100 loops

Load: 0.56

 

Samples

Avg. response time (ms)

Min. response time (ms)

Max. response time (ms)

Std dev

Error %

Throughput (pages/sec)

Throughput (kb/sec)

Avg. transferred bytes

Homepage

1300

489

435

789

16.55

0

16.15

874.60

55442

Landing Page

1300

149

140

249

6.59

0

16.30

515.39

32380

Node

1300

149

141

760

18.10

0

16.30

715.18

44918

TOTAL

3900

262

140

789

161.18

0

48.28

2086.34

44246.67

 

48 concurrent visitors, 60 loops

Load: 0.79

 

Samples

Avg. response time (ms)

Min. response time (ms)

Max. response time (ms)

Std dev

Error %

Throughput (pages/sec)

Throughput (kb/sec)

Avg. transferred bytes

Homepage

2880

749

420

4564

425.14

0

32.70

1770.37

55442

Landing Page

2880

269

145

9375

380.96

0

32.84

1038.30

32380

Node

2880

281

146

9442

437.14

0

32.83

1439.89

44918

TOTAL

8640

433

145

9442

471.34

0

97.59

4216.63

44246.67

 

100 concurrent visitors, 30 loops

Load: 0.9

 

Samples

Avg. response time (ms)

Min. response time (ms)

Max. response time (ms)

Std dev

Error %

Throughput (pages/sec)

Throughput (kb/sec)

Avg. transferred bytes

Homepage

3000

1411

250

16298

1373.02

0

33.71

1825.40

55442

Landing Page

3000

581

144

10285

1110.44

0

33.86

1070.72

32380

Node

3000

554

144

10044

1023.61

0

34.15

1498.20

44918

TOTAL

9000

849

144

16298

1243.76

0

100.80

4355.42

44246.67

 

Finally, I ran one test with authenticated users so that I can compare the performance of serving anonymous users to that of serving authenticated users.

13 concurrent visitors, 30 loops, authenticated user

Load 14.51

 

Samples

Avg. response time (ms)

Min. response time (ms)

Max. response time (ms)

Std dev

Error %

Throughput (pages/sec)

Throughput (kb/sec)

Avg. transferred bytes

Homepage

390

2216

1010

4017

487.53

0

2.11

135.61

65873

Landing Page

390

1874

896

3471

422.00

0

2.12

89.07

43025

Node

390

1900

903

3642

478.98

0

2.13

116.30

55933

TOTAL

1183

2003

896

4017

493.82

0

6.27

334.87

54675.93

(The line of the login page is not shown)

Conclusion

The first thing that catches the eye is that the throughput is 1/7th as high for authenticated users as it is for anonymous. This stems from the fact that Drupal page caching is enabled on the site, and anonymous users are served from cache, while pages are regenerated for every pageload for authenticated users. This test also increased the server load to 14.51, which indicates a bit of an overload. Considering that the server is powered by an Intel Xeon L5420 processor with 4 cores, the server load should not stay over 4 for a longer period, as this means the full utilization of the 4 cores. For anonymous users, it does not get close to being overloaded for up to 100 concurrent visitors.

Next thing I noticed is that the front page loads considerably slower than the other pages. This is an unexpected outcome, because if page cache is enabled, then all the pages should be served from cache, in which case I do not see any reason why the front page could be that much slower. This may be something that requires further investigation on my part.

One piece of the test results that can be compared with the data available in Analytics is throughput. From the number of pageviews, one can calculate the throughput necessary to server the given number of requests. I used the data from the spike in the last figure as a basis of comparison. Applying the formula Number of Pageviews / Length of Time Interval = Throughput, we get

5,328 requests / (60 minutes * 60 seconds) = 1.45 requests / second

which is well below the capacity measured for up to 100 concurrent anonymous visitors. For authenticated users, it would be really close to the rate that the server can actually serve. This should be taken into consideration, should the site decide to open up registration and encourage users to log in.

It is important to note that the factor between concurrent users and the number of pageviews – or Average Pageviews, as Analytics calls it - will vary. A small number of concurrent visitors can initiate more requests on one site than a larger number of visitors on another site. For that reason, knowing that the server can deal with a given number of concurrent visitors may or may not be enough depending on how many pageviews those visitors generate.

38 comments

Hi Gergely,

It seems like a great job to me! Jmeter is a good tool but fall a bit short especially on the analytics side. If you want greater details on your analytics, especially on those coming from your servers, I'd suggest you try your performance test using CloudTest Lite. It will allow you to correlate performance data with performance measurement coming from your infrastructure/servers, in real-time. Can't beat that! :-)

I'd be very interested to get your opinion on how much further you can get with CloudTest Lite.

How about you give it a try? It's free. http://cdn.soasta.com/cloudtest-lite-download.htm

Let me know if you need some help!

Fred

by Will (not verified) on Tue, 03/20/2012 - 9:38pm

Fred,

The only other real problem is that if someone decides to test with more 100 threads (users,) your lite version will not allow it. JMeter, with it's lack of graphing does grant us poor folk the ability to test with higher threads.

I know, the answer is to purchase CloudTest for $$$$.

Gergely Lekli's picture

by Gergely Lekli on Wed, 07/20/2011 - 4:12pm

Hi Fred,

Undoubted, JMeter has its shortcomings. I would have loved to include some nice looking graphs in the post, and, of course, they would have shown more than just the numbers, but I was not able to find a way to have JMeter's graphs display numbers on their axes. Graphs really do not say much without the numbers.

Thank you for your suggestion. I will take a look, and even do a comparison the next time I do a load test. Although I am not sure when I will have a chance.

by mamta (not verified) on Fri, 07/29/2011 - 2:38am

Hi,

I need a small info... in your blog its written for 13 concurrent visitors, 100 loops =
Load: 0.56

My question how this load is calculated?

I looked on blog, but couldn't got any formalae to calculate the load.

Thanks
Mamta

Gergely Lekli's picture

by Gergely Lekli on Fri, 07/29/2011 - 8:21am

Hi Mamta,

You can use the top or uptime linux command to monitor the load. There is no need to calculate it, these commands will show you the load average for the past 1, 5, and 15 minutes. I used the first value, which is 1-minute average.

by chaitu (not verified) on Mon, 10/24/2011 - 8:29am

Hi,

I need to put signup load test using j mater, How can I set those No of users in j mater . Please Help me If you have any idea
Thanks in Advance.
chaitu..

Gergely Lekli's picture

by Gergely Lekli on Tue, 10/25/2011 - 4:48pm

Hi Chaitu,

The 'Number of Threads' setting controls how many concurrent requests will be sent. This would be what corresponds to concurrent users. I hope this is what you meant.

by Software Perfor... (not verified) on Wed, 12/21/2011 - 4:33am

What is the best tool for software testing? If I am newbie then where should I go for software testing.

Gergely Lekli's picture

by Gergely Lekli on Wed, 12/21/2011 - 9:56am

What kind of tests would you like to run? I'll try to make recommendations if I can.

by Manoj (not verified) on Sat, 12/24/2011 - 11:31pm

I am interested in learning peformance test using Jmeter . I tried a simple scenario of single user doing one transaction on Google home oage ( Google HOme -page ) . I am interested to know more about using jmeter like browsing through the google. Searching an information, accessng that URL..etc....Pl advise how to go about it . Regards, Manoj.

Gergely Lekli's picture

by Gergely Lekli on Tue, 12/27/2011 - 10:19am

As far as I know, JMeter will only make simple page requests while measuring the performance, but I don't think it can do things such as executing a search on your behalf and browsing through the results. But someone correct me if I am wrong.

by alice (not verified) on Thu, 12/29/2011 - 8:54am

Hi, thanks for your post, it was interesting to read it. But I have some doubts about the ability of jmeter in rendering a page. I have to load test a web application, I just need to load a page which shows a complex list of items and I should see the response time for the user in case 100 users load the same page more or less at the same time. The results with my simple jmeter test plan are definitely too good. You say "the test results include every factor that comes into play when someone requests a page, including network latencies as well as page rendering times.". But many other (more or less official) pages about jmeter say something like "JMeter does not execute the Javascript found in HTML pages. Nor does it render the HTML pages as a browser does".
So I have a lot of doubts on the relibility of my results (by the point of view of the rendering time of the page for a user). If you can clarify this issue, I will be very grateful! Thanks!

Gergely Lekli's picture

by Gergely Lekli on Thu, 12/29/2011 - 9:43am

It is indeed true that javascript is not executed and the HTML is not rendered in these tests - and I believe this is by design. JS execution and rendering are carried out by the browser on client side, whereas JMeter measures the performance of the server. As a consequence, if the tests included JS and HTML rendering, test results would vary based on the strength of the computer that happens to run the tests against the server. I misspoke when I said page rendering times were measured, thanks for pointing out.

Nevertheless, I see that someone may want to measure JS execution times to optimize the script, but this is something I would do in a separate session, as it does not seem relevant to me to mix server and client side measurements into one test.

by shital (not verified) on Fri, 12/30/2011 - 2:14am

IT nice article and effective too thanks.Can u please tell us 100 concurrent visitors, 30 loops ,48 concurrent visitors, 60 loops loops variation how u calculate?.

Gergely Lekli's picture

by Gergely Lekli on Fri, 12/30/2011 - 9:19am

I had previous Analytics data available to me, and I used that to estimate the expected load. The formula to calculate the number can be found above. If you do not have any previous statistics, you can make an educated guess about how many visitors are likely to hit the site, and then gradually increase the load to see what happens.

by shital (not verified) on Sun, 01/01/2012 - 11:23pm

thanks

by Gurudutt (not verified) on Fri, 01/13/2012 - 4:03am

I am adding blog and saving it, after saving, it generates the node id which I want to extract, I tried with regular expression but I am not able to get the value of the node id.
Node id get generated when I save the blog and I want to extract the value from the same page.
How can I get this value?

Gergely Lekli's picture

by Gergely Lekli on Fri, 01/13/2012 - 9:52am

Hi Gurudutt,

I have never done anything like that with jMeter. I cannot imagine a load test scenario where I would need to create nodes in the course of the test. Node creation events are usually so scarce compared to the number of times they are viewed that they are only responsible for a small portion of the server load.

by Manoj (not verified) on Sat, 01/28/2012 - 11:25pm

I would like to know the pre requisites to start with Jmeter performance testing. What level of technical knowledge is required . Pl advise.

Gergely Lekli's picture

by Gergely Lekli on Mon, 01/30/2012 - 9:22am

I believe having a general understanding of how the server works is good to have in order to be able to interpret the test results. There is fairly good documentation on Jmeter, head over to jmeter.apache.org, and you will find what you need to get started.

by mahesh (not verified) on Mon, 02/06/2012 - 2:35am

hi ,
this is mahesh,i am new to jmeter ,my question is i am not able to access my applications which are in my tomcat while i am trying to record with http proxy server but at the same time i am able to access
the applications which are in other applications in tomcat:through ip address,why i am not able to record those:can any one suggest me regarding this..thanks in advance.

Gergely Lekli's picture

by Gergely Lekli on Mon, 02/06/2012 - 9:18am

This is too little information to advise you, but if the problem is that you can only access your web application through the ip address, then this issue might not be in the scope of this article.

by Prashant Patel (not verified) on Wed, 03/14/2012 - 4:02pm

Very interesting article, especially for new comers. I am trying to calculate concurrent user based on following information.

concurrent_users = (monthly_visits * time_on_site) / (3600 * 24 * 30)
concurrent_users = (175,963 * 911 sec) / (3600 * 24 * 30)
concurrent_users = (160302293) / (2592000)
concurrent_users = 62 users

Is this correct way to calculate?

Thanks,
Prashant

Yes, this seems right. The (monthly_visits / (3600 * 24 * 30)) part in your formula coincides with what I called Rate of Incoming Visitors, that is visitors/second.

by Anonymous (not verified) on Thu, 03/15/2012 - 5:56pm

I am little confused because our sys admin sent me a web logic concurrent session graph, stating that there were 1247 concurrent users. Could this be possible?

Thanks

Gergely Lekli's picture

by Gergely Lekli on Thu, 03/15/2012 - 6:17pm

The number you get from the Analytics data is an average, which means any value can occur in the period you are taking the average of.

For example, let's suppose your GA stats say that you have 100.000 visitors in a given month, with 1 minute average time-on-site. The formula gives ~2.3 concurrent visitors on average.
If all that 100.000 people happens to hit the site in the first minute of the first day, you get effective 100.000 concurrent visitors in that moment. Not likely, but theoretically. If your visitors come one by one, and, for some reason, noone visits your site as long as someone is visiting it, you get an effective 1 concurrent visitor maximum.

You are definitely going to see numbers well above the average. So, to quote myself, the statistics does not tell us much about the actual values at any given moment.

by Bhushan (not verified) on Wed, 04/04/2012 - 11:47pm

Hi,

For what purpose simulated concurrent users are in JMeter Test ?
How they perform in load/performance testing ?

Thanks,
Bhushan

Gergely Lekli's picture

by Gergely Lekli on Thu, 04/05/2012 - 9:15am

The purpose of simulating concurrent users is that you can see how the site performs when many users visit the site at the same time. A certain number of visitors hitting the site at the exact same time is a larger stress to the server than the same number of users visiting at various times spread across a longer period.

by Itai (not verified) on Sun, 05/20/2012 - 4:59am

> purpose of simulating concurrent users is that you can see how the site performs when many users visit the site at the same time.

Gergely, thanks for the well informed post. I enjoyed it and learned a lot!!!
Question: my colleague is working with BlazeMeter.com as a "Jmeter Cloud solution" but I am unsure it is good enough for my needs. Can you help? Have you got any inputs?
Thanks a Million!

Gergely Lekli's picture

by Gergely Lekli on Mon, 05/21/2012 - 7:38am

I don't have experience with BlazeMeter, so unfortunately I cannot give any input on it.

by Dzmitry Kashlach (not verified) on Mon, 07/02/2012 - 6:06am

Hi Itai,
I'm Blazemeter Performance Analyst, you can find me at linkedin,
http://www.linkedin.com/pub/dzmitry-kashlach/49/2a2/442
Also I've created a set of JMeter Tutorials,
http://blazemeter.com/blog

We suggest out-of-box load testing service, that is fully compatible with Apache JMeter. You can use automated scripting feature or upload your own test-plan.
If you have some questions, you can contact me via linkedin or e-mail, dzmitry.kashlach@blazemeter.com

Thanks,
Dzmitry.

by Bhadra (not verified) on Mon, 09/24/2012 - 6:51am

Hi

Iam new to use JMeter . Can we use JMeter for loadtesting on application developed by PHP.

Gergely Lekli's picture

by Gergely Lekli on Mon, 09/24/2012 - 9:09am

Yes, it can be used on any application, not just Drupal. For instructions on setting it up for any scenario, see their manual:
http://jmeter.apache.org/usermanual/index.html

by bhadra (not verified) on Tue, 09/25/2012 - 2:57am

Hi, LeKli
Thanks for your reply .

1)Please help me out How to do the Proxy settings of jmeter and firefox .
2)How to record transaction wise ex:Login, Homepage,Logout.

Gergely Lekli's picture

by Gergely Lekli on Tue, 09/25/2012 - 9:09am

I am glad you are interested in using Jmeter. However, your questions are too broad and complicated to be answered in a blog comment. Discussing how to set up Jmeter for specific tasks is out of the scope of this article.

by pj (not verified) on Mon, 10/15/2012 - 9:47pm

hi all,

I want to update my database through my test case. The scenario are as
follow:

i am using the recording process:

*1. login into the site
2. there is one query form. submit that form
3. logout from the site*

when i am running this scenario(*note- i update the values in Jmeter )*
This scenario doesn't show any error in summary report but when i am
checking database, there is no updates in database

*Can any one please tell me what i do so that the values update into the
database.*

--> *if i change the credentials in login sampler than still it doesnt show
any error in summary report*.
but i am getting one line in error section --> *"test has ended on host
null"*

Can any one please tell me what i do. where i am wrong.

Thanks in advance,
PJ

by Dileep (not verified) on Wed, 01/30/2013 - 8:55pm

Hi Gergely,

Please help me out in this,

How to save summury report table every 10seconds(to differnt file(.csv) or append to same file with some separator in between), and i am doing load testing remotly using Non-Gui mode(thrugh putty).

Thank you..............,

Thaks,
Dileep

by Anonymous (not verified) on Fri, 04/05/2013 - 12:34pm

Use perfmon plugin with Jmeter

Post new comment