Stress test for WordPress

One of the common concerns of those who have a website with WordPress is knowing how much traffic and at what speed the website will work for users. And the tool for this is that of a stress test.

This tutorial has been created on a VPS. You can create your own VPS from 3€/month.

In addition, you have the possibility to create your VPS with the WordPress image in one click.


To do these tests, we can use AB (Apache HTTP server benchmarking tool), but also a more modern tool in wrk call (to HTTP benchmarking tool).. The tool must be on a machine connected to the Internet if we want to make calls to a public website. In this case, the example will be about Ubuntu.

Installing the tool

The first thing we have to do is download and compile the tool. Once finished it will be available on the server.

apt -y install build-essential libssl-dev git unzip
git clone wrk
cd wrk
cp wrk /usr/local/bin

From this moment on, we can run the tool and see its options.

Usage: wrk <options> <url>
    -c, --connections <N>  Connections to keep open
    -d, --duration    <T>  Duration of test
    -t, --threads     <N>  Number of threads to use
    -s, --script      <S>  Load Lua script file
    -H, --header      <H>  Add header to request
        --latency          Print latency statistics
        --timeout     <T>  Socket/request timeout
    -v, --version          Print version details
  Numeric arguments may include a SI unit (1k, 1M, 1G)
  Time arguments may include a time unit (2s, 2m, 2h)

Doing a first test

Stress tests can be several, so we will do a first test, simple, which is to access, a lot, to the main page of our site.

The configuration will depend a lot on the resources of the machine. In this case, we are going to do a test on a VPS that has 4 CPUs, and we will do a test for 30 seconds. Depending on the configuration we have, we can add more or less simultaneous users (per CPU), in this case 250 users. In total it means that there will be 1,000 users in 30 seconds.

wrk -c250 -d30s -t4 --latency --timeout 5s
  • c: 250 wire connections
  • d: 30 seconds
  • t: 4 threads (CPU)

The result will look like this:

Running 10s test @
  1 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.85s   902.12ms   3.56s    83.67%
    Req/Sec    15.08      7.34    40.00     85.71%
  Latency Distribution
    50%    3.31s
    75%    3.39s
    90%    3.44s
    99%    3.53s
  147 requests in 10.02s, 1.40MB read
Requests/sec:     14.67
Transfer/sec:    142.55KB

To adjust the requests, you should take into account as a base the CPU of the machine, and the number of requests (if you want to test normal, 100 is fine, if you have mounted something very well, an interesting test is 1,000). The time, the one that is considered… between 30 seconds and 1 minute, is fine.

Stressing the login

No doubt testing the main page is fine, but as there may be cache, it actually tests us a lot, so maybe we can stress the system by accessing the administration panel (it can be from a user without permissions). In this case the test will be more in the database.

The first thing we will have to do is create a special configuration file. Here we will include the login page, and the username and password of a user.

vim wplogin.lua

There we will include the access data and the test.

wrk.method = "POST"
wrk.body   = "log=usuario_de_test&pwd=contrasenya_del_usuario&wp-submit=Acceder&testcookie=1&redirect_to="
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

In this case, the test cannot be as large as in the previous case. What we will test will be how many logins/second can be done. For example, let’s test if you can make 10 logins per second.

wrk -c100 -d10s -t1 --latency --timeout 5s -s wplogin.lua

Making requests to multiple URLs

One of the things that is usually tested is to call only a single URL, and perhaps the most interesting thing is to choose and test different URLs: the main page, a category, an entry, a page, a product …

vim wpurl.lua

There we will include the access data and the test.

init = function(args)
  local r = {}
  r[1] = wrk.format(nil, "pagina/")
  r[2] = wrk.format(nil, "post/")
  r[3] = wrk.format(nil, "tag/etiqueta/")
  r[4] = wrk.format(nil, "category/categoria/")
  req = table.concat(r)
request = function()
  return req

Now we will do the test so that you call, randomly, to these URLs…

wrk -c1k -d1m -t16 --latency --timeout 5s -s wpurl.lua

And to test and optimize.

About this document

This document is regulated by the EUPL v1.2 license, published in WP SysAdmin and created by Javier Casares. Please, if you use this content in your website, your presentation or any material you distribute, remember to mention this site or its author, and having to put the material you create under EUPL license.