Load Testing with Locust
How to test if your web application can handle high traffic
Once you have deployed your application, a good idea is to test whether your server will be able to handle the expected traffic. First, you want to make sure it won‘t crash. Second, you want to enable the users of your application to have a smooth experience, and this means fast response times.
If a user visiting your app has to wait 500 milliseconds for each API call, your app is in trouble.
So, how would you test the resilience of your server, if for example , you had 300 users visiting your app at the exact same time.
Maybe call 299 of your friends and have them all visit the url at the same time?
Ok, dumb joke :D . What you need is a load testing tool. There are a number of good ones. JMeter is probably the most popular, but I would argue that Locust is way better, especially if you know at least a little bit of Python.
JMeter is an great tool, and it‘s built with Java. It has a neat UI , so you don’t even need to write much code to get it working. However, for every concurrent user that you simulate, JMeter spawns a new thread, and this can stress you local machine more than it will potentially stress the remote server you are testing.
Locust, on the other hand, uses an asynchronous framework called Gevent, so it basically simulates hundreds of users on one thread.
Now, as for simplicity, Locust doesn’t have a UI for creating the test , like JMeter does, but the code is so simple, even a Python newbie will be able to write a load test. Let me demonstrate:
First, we need to pip install Locust, so that we have it locally:
Next, let’s create a python file and name it locustfile.py . It needs to be called that because that way Locust will know which file to look for when running the load test. Now, let’s type out the code:
Let’s go over what this code does.
The top two lines import the Locust library, and the built-in logging module.
Next, we define a class and call it QuickstartUser (but you can call it whatever you like) , and it inherits from the HttpUser class that is part of the Locust library. This inherited instructs Locust that this is the simulated behavior of a single virtual user.
We then define two methods using the @task decorator , which tells Locust that each of these methods is an endpoint we are testing.
In this case, we have two endpoints - /hello , and / (the home page) . The (3) in the second task means, we want a weight of 3 on that particular endpoint. This means that the load test will target this endpoint 3 times more than the /hello endpoint.
Finally, the @events.quitting.add_listener decorated function defines the thresholds for our test. For example, if the average response time from our server is above 200 milliseconds, the test will fail, giving an exit code of 1. This means, that if we were to run this load test in a CICD tool like Jenkins, the CICD pipeline would fail if this threshold wasn’t met.
Ok, great, but how do we run the actual test?
Easy, just type in your terminal locust (make sure you are in the directory where you locustfile.py is located) :
We can now head to our browser, to localhost:8089 , just like the terminal output tells us to:
There you are, a nice UI ! All you have to do now is to enter the number of users, the spawn rate , and the host, and click the “start swarming” button.
You should see something like this:
Note that all of the requests are failing, but that is because I am using an imaginary URL.
This is a good time to mention that YOU SHOULD ONLY USE LOCUST ON URLS THAT ARE YOURS, OR THAT YOU HAVE BEEN GIVEN EXPLICIT PERMISSION TO TEST !
I’m not kidding. If you load test someone else‘s web page and as result of that the page goes down, you are basically simulating a DDOS attack, and could be in serious trouble. So , no monkey business please :D
Finally, as I mentioned, you can also run it from the command line as part of a CICD script. It‘s as simple as :
locust --csv=(nameOfOutputFile) --headless --host http://yourURL -u 300 -r 3 --run-time 30s
The csv flag is for getting the results of the test in csv format for analysis.
I would also like to mention that the official Locust docs are really nice, here is the link :
Thanks for reading, hope you enjoyed!
Experienced Python Developer with a demonstrated history of working in numerous software development roles and a thorough understanding of the complete software development process. My main skills include Python, Flask,AWS, REST API development, Test Automation , Docker, Redis and SQL .