Photo by Adli Wahid on Unsplash
Super Simple Guide for Load Testing Using Vegeta
A guide to measuring your application limit, better stressed out now than later
What is load testing?
In simple meaning, a load test is to determine the behavior of how the application, which can be API endpoints, will respond when multiple simultaneous users try to use the application / APIs.
There are many ways to load test applications/APIs and Vegeta is one of the easiest tools to perform load testing on your APIs or applications.
Why Vegeta?
There are many load testing tools available. Apache JMeter, Locust, and some Load-test as a Service also provide the functionality.
Writing a locust file is not convenient for some peers since it requires basic Python and is not straightforward, while JMeter has lots of concepts to be understood and has a steep learning curve.
Vegeta comes with binary (a go-binary and also a library if we want to use it within our application) so it is easy to install and start. Just define the URL and how many requests then Vegeta will hit based on that definition.
Vegeta is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate. It can be used both as a command line utility and a library.
Install Vegeta
Head to Vegeta's releases page and pick the latest release to download.
Linux User
$ cd ~/Downloads
$ wget https://github.com/tsenart/vegeta/releases/download/v12.8.4/vegeta_12.8.4_linux_amd64.tar.gz
$ tar -zxvf vegeta-12.8.4-linux-amd64.tar.gz
$ chmod +x vegeta
$ ln -s ~/Downloads/vegeta ~/bin/vegeta
$ vegeta --version
Mac User
$ brew update && brew install vegeta
$ vegeta --version
First Attack
There are multiple ways to use the Vegeta, one of the simplest ways to get the load testing result is by using a command line, this is also to make us easier to analyze.
Your first load testing command can be like this:
$ printf "GET https://yourdomain/api/endpoint" > target.list
$ vegeta attack -duration=5s -rate=200 -targets=target.list | vegeta report --type=text
The breakdown of the command is:
Write the endpoint to the file, named target.list.
vegeta attack
is the main command that ran the Vegeta load test with 120 requests per second (rate
) for 300 seconds (duration
) to the target.list file (target
).Then display the report of attack as text.
The sample report is in the following format:
Requests [total, rate, throughput] 1000, 200.20, 197.93
Duration [total, attack, wait] 5.052s, 4.995s, 57.304ms
Latencies [min, mean, 50, 90, 95, 99, max] 34.194ms, 245.024ms, 173.533ms, 386.689ms, 484.755ms, 2.973s, 3.207s
Bytes In [total, mean] 26000, 26.00
Bytes Out [total, mean] 491000, 491.00
Success [ratio] 100.00%
Status Codes [code:count] 200:1000
Error Set:
We can read the report like the following:
Attack of 1000 requests spread over 5 seconds at 200 RPS (Request per Second).
The minimum response time was 34.194 ms and the maximum was 3.207 s
100% success rate. This means all the requests came back as 200 HTTP Success.
None
Error Set
was provided since we had a 100% success rate.
Multiple Attacks
This is my favorite feature that Vegeta provided, we can easily put multiple URLs or API endpoints to be load tested.
$ printf "GET https://yourdomain/api/endpoint1
GET https://yourdomain/api/endpoint2" > target.list
$ vegeta attack -duration=5s -rate=200 -targets=target.list | vegeta report --type=text
It has a similar command to the previous load test, the difference is just the multiple endpoints that we put on the target.list
:
$ cat target.list
GET https://yourdomain/api/endpoint1
GET https://yourdomain/api/endpoint2
Attack with Headers and Body
If we require to authenticate the request, for example using a Authorization Bearer
on the headers, we can easily do that:
printf "GET https://yourdomain/api/endpoint1
Content-Type: application/json
Authorization: Bearer x5v0_HzUUKFev" > target.list
Again, it has a similar command to the previous load test, if you check the target.list
you will see:
$ cat target.list
GET https://yourdomain/api/endpoint1
Content-Type: application/json
Authorization: Bearer x5v0_HzUUKFev
Adding a request with a request payload to the definition is easy too, you will need to create a file for the body that contains the JSON:
printf '{"answers": [
{"question1": true},
{"question2": false}
]
}' > body.json
Then target.file will be needed to include the body file:
printf "POST https://yourdomain/api/endpoint1
Content-Type: application/json
Authorization: Bearer x5v0_HzUUKFev
@body.json" > target.list
Vegeta command like usual:
$ vegeta attack -duration=5s -rate=200 -targets=target.list | vegeta report --type=text
Graphical Reporting
It comes in handy with Vegeta if we want to analyze further by using a graphical chart for our load testing result. The first thing you will need to do is to store the result in a file:
vegeta attack -duration=5s -rate=200 -targets=target.list | tee results.bin | vegeta report
As you can see on the command above, we have tee results.bin
. tee
command reads the standard input and writes it to both the standard output and one or more files so at the end of load testing, we will have a results.bin file to look.
$ cat results.bin | vegeta plot --title="My Load Testing" > loadtest.html
This Vegeta command generates an HTML file that contains the graph of our load testing results.
Final Attack, *read: Thought
There are lots of Vegeta features uncovered in this article but for now, we can conclude that Vegeta is easy to use and helps us to determine our application behavior when concurrence users are accessing our application.
I once used Vegeta to load test one of our services in my previous company, Quipper, for a past event with 100k concurrent users so we could measure, predict, and scale up our service correctly. You know what, it was a big success for our service squad, thanks to Vegeta!
Bye for now~
p.s. Don't forget your monitoring tools while doing load testing.