Simulating browsers using JMeter
JMeter is commonly used to stress test webpages by simulating multiple users concurrently visiting a webpage URL. However, for this simulation to be accurate, JMeter needs to be configured correctly so that it behaves like a browser.
In this article, I explain what settings to configure, to make JMeter simulate browser requests fairly accurately.
Before configuring JMeter correctly, let’s understand how browsers work:
- When user enters a webpage URL in browser, it connects to server, starts downloading the page, and starts parsing.
- A browser then creates more threads, each of which opens a new connection and fetches one of these embedded URLs. Most browsers use a limited number of connections per server (6 in case of firefox at the time of writing) and cap the total number of downloading threads (48 in case of firefox at the time of writing).
- The page is considered loaded when all these embedded URLs have been fetched.
JMeter can simulate this behaviour if the following 2 settings are configured:
- Retrieve All Embedded Resources from HTML Files
This checkbox is found near the bottom of HTTP Request Defaults config elements and HTTP Request samplers.
Add a View Results in Tree listener element if you want to see which embedded resources are downloaded and their metrics. Note that View Results in Table bytes don’t include the embedded resources.
- Use concurrent pool. Size=n
The behaviour of this checkbox and pool size are as follows:
Retrieve all embedded resources from HTML files Use concurrent pool Behaviour Checked Unchecked The main page and its embedded resources will be downloaded in the same thread.
For example, if Thread group is simulating 3 users, Jmeter creates 3 threads – one for each simulated user – named "Thread Group 1-1" to "Thread Group 1-3".
Each of these threads will download all embedded resources sequentially in the context of their respective thread.
If page P has resource A,B and C, Jmeter will download them as follows:
~ThreadGroup1-1 : p, A, B, C (downloaded one after another)
~ThreadGroup1-2 : p, A, B, C (downloaded one after another)
~ThreadGroup1-3 : p, A, B, C (downloaded one after another)
As usual, JMeter creates threads named "Thread Group 1-k" to simulate users.
In addition, for every one of these threads simulating a user, JMeter creates separate threadpools of size x with thread names like pool-n-thread-m.
The main page is downloaded by the user’s thread "Thread Group 1-k" while the embedded resources are downloaded by its associated threadpool with thread names like pool-n-thread-m.
So to simulate browsers, check the ‘Use concurrent pool‘ checkbox and specify a reasonable pool size (4-8 seems typical for browsers).
However, when setting the concurrent pool size, keep in mind the number of users being simulated, because a separate threadpool is created for each of these simulated users. If there are many users, too many threads may get created and start affecting the response times adversely due to bandwidth contention at the JMeter side. If many users are to be simulated, it’s recommended to distribute JMeter testing to multiple machines.