

One of the most important things to know when starting Web applications is under what amount of load it will crash. Every server has its limits. Not knowing what those limits are can do a lot of damage to your company's image.
Before launching a new version of your project, it is advisable to run some load tests on the application. The results of these tests will tell you how many concurrent visitors your application can handle in the current infrastructure and which server resource is most likely to crash first.
By knowing how many concurrent users your application can handle, you can adjust the configuration of the servers to ensure that the infrastructure can handle the predefined number of visitors. You can add alerts to specific thresholds so you have time to scale up when your application needs additional resources. By being aware of your application's limitations, you can adapt to an increase in traffic.
How can I create load tests?
The first thing you need to do before you can create load tests is to specify test scenarios. An important part of determining these scenarios is knowing the visitor's behavior in the Web site. For new sites, this can be a calculated guess. For existing Web sites, you can retrieve this information from tools such as Google Analytics.
For example, if you are creating an average Web store, you can break down your traffic into the following scenarios:
- 20% Homepage
- 20% Landing page visitors
- 20% Catalog / product page visitors
- 20% Search visitors
- 20% Ordering visitors
While running the load test, the traffic is spread across these scenarios. This gives you a realistic distribution of the application load.
Once you have specified the above scenarios, it is time to write the load tests. Our weapon of choice is JMeter. Internally, the tool stores its configuration in an XML format. Fortunately, it also provides a GUI that makes it easy to configure the test suites. You can imagine JMeter as a curl workflow tool on steroids. The JMeter project consists of the following main elements:
- Test plan: Contains user-defined variables such as environment, path, ...
- Thread groups: Is similar to a test suite
- Configure elements: You can add tools that include cookie managers, browser cache, ....
- Controllers: A controller consists of samplers and can include logic such as if, while, ....
- Sampler: Will execute HTTP requests.
- Pre-processor: Will perform advanced things like rewriting URLs before sending the request.
- Post-processor: Collects data from a response. For example, you can parse JSON or form values based on the CSS selector path.
- Assertions: Validates whether a response contains the value it expects to be available.
- Listeners: Listeners are typically used to display reports and graphs.
- Timers: You can specify arbitrary wait times between requests.
Using the blocks above, you can build the test scenarios you determined earlier.
As you can see, in this test scenario, we will load the Google homepage and verify that the response contains the word “Search.” We will also store a fictitious CSRF token from the form in a variable using an XPath extractor. By adding a cache and cookie manager, we simulate a real browser. When the test scenario contains a second request, it will serve the stored images directly from the cache server instead of loading them from the remote server.
What environment should I run my loading tests on?
To get the best idea of how much traffic your infrastructure can handle, it is best to run these tests on the production system. You can try to find a time when there is not much traffic on the website and do this during those hours. If this is not possible, it is advisable to set up a duplicate environment with exactly the same resources. It is possible to downgrade the resources, but then you don't know at how many connections the application will crash. An advantage of downgrading the resources is that you can find the weakest service with less effort.



How do I conduct my loading tests?
One of the disadvantages of JMeter is that it runs on the system on which it is installed. This limits you to the resources of your computer or the bandwidth of your network. As you can imagine, this is not enough to detect the limits of your system. Therefore, we will have to run the tests through a distributed network of visitors.
One of the services that provide distributed visitors for load testing is BlazeMeter. You can create a new load test on BlazeMeter and upload the JMeter configuration file. Then you can specify the location where you want to run the test. Possible options are AWS, Google Compute or Microsoft Azure. Next, you can specify how many concurrent users you want to simulate. You can distribute them across multiple threads and multiple physical engines. Note that the number of users is multiplied by the number of threads in your JMeter project. Finally, you can choose how long you want to run the test or how many iterations to run. The configuration can look like this:
How can I monitor my server resources?
As you can see, New Relic's statistics include information about response time, number of errors and such general statistics. If you want to know how load is infecting your infrastructure, you should enable additional resource logging during load testing.
During testing, we monitor server processes with the top command. We also install New Relic on the machines so that we can generate advanced system statistics afterwards. This way it is possible to display advanced statistics such as: CPU usage, memory usage, network traffic, application errors, mysql errors, .... during the load test.
Of course, it is possible that the performance problems are related to slow code in your application. The Transactions section in New Relic shows the top 10 slowest pages with their stack traces. This way, you can quickly detect which code is causing the slow response times. You can improve the code or add some caching and run the load tests again. Going one step further, you can add automated Blackfire tests for this particular scenario to ensure that some of the code will never slow down your application again.
In New Relic, it is possible to create custom load dashboards. If you regularly run load tests on your system, you can use this dashboard as a reporting tool. This allows you to run load tests and report the results in a few hours. The dashboard can also be used to monitor real traffic on your application.