The objective of this quick how-to is to explain how to perform a stress test against your site and see how it behaves under extreme load. The Open Source tool that we are using for this test is the HTTP benchmarking tool wrk.

What is a (DoS) Denial-Of-Service attack:

A Denial Of Service (DoS) is a type of an attack where the attacker prevents authorized users to get access to a service. Most common method of DoS involves flooding the service with so much traffic or data requests, such that the service wouldn’t be able to respond to legitimate users until the malicious flow has been ended. We will use the HTTP benchmarking tool, wrk, to emulate that type of attack.

How to check quickly if your website is protected against DoS attacks?

In computing, what is a benchmark:

Per wikipedia, benchmark is:

In computing, a benchmark is the act of running a computer program, a set of programs, or other operations, in order to assess the relative performance of an object, normally by running a number of standard tests and trials against it. The term benchmark is also commonly utilized for the purposes of elaborately designed benchmarking programs themselves.

Two key characteristics of a benchmark are:

  1. Must be repeatable.
  2. Must be quantifiable.

What is wrk:

For running the load test against our website we are using wrk, per their official documentation:

wrk is a modern HTTP benchmarking tool capable of generating significant load when run on a single multi-core CPU. It combines a multithreaded design with scalable event notification systems such as epoll and kqueue.

wrk is open source, but before using it, take a look at the cryptography notice at https://github.com/wg/wrk#cryptography-notice

How to install wrk

Ok, finally we will start the testing. Make sure that you are comfortable running commands on the terminal, since there is not a GUI to run wrk at the moment.

  • How to install wrk on Mac

    • Install homebrew, run the following command in a terminal:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    • To instal wrk, run the following command in a terminal:
brew install wrk

  • How to install wrk on the Linux distribution Ubuntu

sudo apt-get update
sudo apt-get install wrk

  • how to install wrk on windows

The Windows users will need to install Ubuntu first per this link and run the two commands above afterward.

How to stress test your site

The basic usage of wrk looks like this:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html

The command line options valid are:

-c, --connections: total number of HTTP connections to keep open with
                   each thread handling N = connections/threads

-d, --duration:    duration of the test, e.g. 2s, 2m, 2h

-t, --threads:     total number of threads to use

-s, --script:      LuaJIT script, see SCRIPTING

-H, --header:      HTTP header to add to request, e.g. "User-Agent: wrk"

    --latency:     print detailed latency statistics

    --timeout:     record a timeout if a response is not received within
                   this amount of time.

I will run a benchmark for 90 seconds, using 10 threads, and keeping 100000 HTTP connections open.

wrk -t10 -c100000 -d90s https://davidloor.com --timeout 3s --latency -H 'Client: wrk terminal'

Quick explanation about what I am doing with the passed options:

-t10: Use ten separate threads
-c100000: Open 100000 connections
-d90s: Run the test for ninety seconds
https://davidloor.com The target website
--timeout 3s: Define a three-second timeout
--latency: print detailed latency statistics
-H 'Client: wrk terminal': Pass a Client header

So, we can say that the stress test is trying to emulate 100000 users opening the website’s homepage multiple times for 90 seconds.

Important: While running the stress test, open the website and also try to log in (if the website has this capability), if the site loads quickly as usual, you may assume that it is protected against simple DoS attacks and the server is able to handle a significant load. If the site takes some time to load, or it displays an error, you got a problem with the website and you should ping your hosting provider about it. In some cases the site won’t be able to recover by itself and it may need to restart some services.

Analyze the Output

After running the command I get this:

Running 2m test @ https://davidloor.com
  10 threads and 100000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   528.12ms  527.33ms   2.99s    87.92%
    Req/Sec    20.30     16.93   116.00     74.75%
  Latency Distribution
     50%  356.27ms
     75%  638.27ms
     90%    1.20s 
     99%    2.62s 
  11662 requests in 1.50m, 735.63MB read
  Socket errors: connect 97681, read 117, write 0, timeout 1581
Requests/sec:    129.43
Transfer/sec:      8.16MB

It gives a quick summary about how long the test ran, and the website (https://davidloor.com) that was tested. It also shows the normal distribution parameters for latency and Req/Sec. In shows that in 1.5 minutes, wrk did 11662 requests and transferred 735.63 MB of data.

Are the Avg. values for Latency and Req/Sec good? It depends on each individual situation. We should always try to keep the Latency low and the Req/Sec high, and you should keep in mind that the higher the number of connections the lower these 2 values will be.

Conclusions

  1. You can stress test your site quickly with wrk. https://github.com/wg/wrk
  2. The command to run a stress test, after installing wrk, is: `wrk -t10 -c100000 -d90s https://davidloor.com –timeout 3s –latency -H ‘Client: wrk terminal’`
  3. Run the wrk command, and at the same time, try to load the site in your browser and see if you experience any slowness.
  4. There are free resources to improve your website performance without adding more resources to the server(s) like using a free CDN, such as cloudflare.
  5. If you have a CDN, make sure that you are fully utilizing its benefits.

Disclaimer: The information available on this blog post is for educational purposes only. I am not responsible about how you use the information here.