Modern HTTP benchmarking tool

I'm using wrk for my testing work, but my service is not completed or strong presently.
Sometimes the test result just showed me that there were some timeout out of the test.
I have not found any hint in the existing issues or documents related to such a requirement.
I want to know how the request looks like when a timeout is triggered.
I'd appreciate it if someone could tell me whether there is a way to achieve this without modifying the source code?

Can you please provide a sample lua script which will make wrk wait for a configurable amount of time after each HTTP request?

As shown in


Lines 1 to 18 in 7594a95

-- example script that demonstrates response handling and
-- retrieving an authentication token to set on all future
-- requests
token = nil
path = "/authenticate"
request = function()
return wrk.format("GET", path)
response = function(status, headers, body)
if not token and status == 200 then
token = headers["X-Token"]
path = "/resource"
wrk.headers["X-Token"] = token

the recommended login approach is for each thread to send a login request, copy the necessary information into the wrk table, then use that information in all subsequent requests. This has at least two downsides

  • The initial request may have much higher cost e.g. latency than subsequent requests and can throw statistics off, especially in short runs.
  • It requires a response() method and calling that method (even if it no-ops for requests after the first) is documented as expensive.

My suggestion is to add support for optional initial_request() and initial_response(status, headers, body) methods. If these are defined, call them immediately after init() (in each thread) for a single request then switch to the usual request() / wrk.request() and response(...) handlers. Reset all statistics after completing the first request. Also, delay the usual wrk.format() call 'til after initial_response(...) returns (removing the need for anything beyond wrk settings in initial_response(...).

How can I carry a ca cert to verify the remote server when I send a request to a https server's domain name?
Just like curl --cacert xxx http://xxx

wrk -c $num -d20 -t $num --timeout 30 -s post.lua

Running 20s test @
100 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 9.40ms 4.03ms 44.03ms 79.32%
Req/Sec 108.74 14.01 262.00 75.71%
216980 requests in 20.10s, 69.32MB read
Requests/sec: 10794.46
Transfer/sec: 3.45MB> xlen cache:stream:enqueue

(integer) 217068

wrk total request number is always greater than received message via save to redis stream

i installed wrk and when i run

wrk -t12 -c400 -d30s

then below error message will be shown

PANIC: unprotected error in call to Lua API (attempt to index a nil value)

with wrk 4.1.0-3 on debian, wrk does not report that the server is refusing some connections and run with fewer connection. This may lead to completely wrong benchmarks due to a missconfigured server.

Hello everyone, hope you are doing great.

I have a specific need in which i need to create jwt token or hmac in the lua request and then send the requests.

I tried to install library or add the compiled files in my project, but in the end it fails(sometime due to openssl and sometimes due to lcrypto). I can explain the errors and share logs here. But before that if any1 has tried this before, can you share how u got it working.

While working on reproducible builds for openSUSE, I found that
our wrk package does not build reproducibly.

I found that the problem comes from the step where luajit produces bytecode.c from wrk.lua because the ordering of hash-table elements is non-deterministic.

for i in $(seq 100) ; do
obj/bin/luajit -b src/wrk.lua out.c ; md5sum out.c
done | sort | uniq -c

      7 1bd4204083654f5bf1cf06c2ef7d66ca  out.c
      1 1ea98f25d56b7e6612e674cd1cbb01e5  out.c
      9 395d32504ba77a8b1e77d6fe3ba65fb0  out.c
      4 3a0670bd7f137eed1689489bfa8fba21  out.c
      9 3bbb121dbe3f5e55f770f2c2fa731088  out.c
     18 41b1073081dee2b966c103b3244260f3  out.c
      6 687ac115ad5a9dddd1be0225fa5a30e8  out.c
      2 8696465af120e9d965cdd06c1db53712  out.c
      2 9ba9f3f208f84b833a6900e0b58e7206  out.c
      2 9c54df99cc9f973e35008fc9c5070f44  out.c
      7 9e710447f23a61dccdd5b0de36e4ea26  out.c
      2 a29bdae6b54fd80dfb26abf84db66cf7  out.c
      9 cb65480a8b62fe920727e59dc0061ebc  out.c
     10 d2abb54e5332ba5b656aa453435e9154  out.c
     11 ec177bda0950f2af6d120dd8351301e0  out.c
      1 f08bed1cbf3d3422caf932e39ecdbd26  out.c
--- old /usr/bin/wrk (hexdump)
+++ new /usr/bin/wrk (hexdump)
@@ -29912,10 +29912,10 @@
  75780 07003d01 06003301 09003d01 08003200  ..=...3...=...2.
  75790 00804c00 0200000b 666f726d 61740009  ..L.....format..
  757a0 696e6974 000a7365 74757000 0c726573  init..setup..res
- 757b0 6f6c7665 0c686561 64657273 0100040b  olve.headers....
- 757c0 6d657468 6f640847 45540968 6f73740e
- 757d0 6c6f6361 6c686f73 740b7363 68656d65  localhost.scheme
- 757e0 09687474 70097061 7468062f 00000000  .http.path./....
+ 757b0 6f6c7665 0c686561 64657273 01000409  olve.headers....
+ 757c0 686f7374 0e6c6f63 616c686f 73740970  host.localhost.p 
+ 757d0 61746806 2f0b7363 68656d65 09687474  ath./.scheme.htt
+ 757e0 700b6d65 74686f64 08474554 00000000  p.method.GET....
  757f0 68747470 5f706172 7365725f 70617573  http_parser_paus
  75800 65000000 00000000 00000000 00000000  e...............
  75810 68747470 5f706172 7365725f 70617273  http_parser_pars

Just curious if anyone noticed if we put response ( hook in lua script, that slows down the benchmark.

With Script

$ ./wrk -c 4 -t 2 -d 60 --timeout 300 -s scripts/setup.lua
thread 1 created
thread 2 created
Running 1m test @
  2 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     0.00us    0.00us   0.00us    -nan%
    Req/Sec     0.00      0.00     0.00      -nan%
  0 requests in 1.00m, 0.98GB read
Requests/sec:      0.00
Transfer/sec:     16.72MB
thread 1 made 3 requests and got 0 responses
thread 2 made 2 requests and got 0 responses

Script without response function()

$ git diff scripts/setup.lua
diff --git a/scripts/setup.lua b/scripts/setup.lua
index 30d72f3..e3b2689 100644
--- a/scripts/setup.lua
+++ b/scripts/setup.lua
@@ -23,9 +23,9 @@ function request()
    return wrk.request()

-function response(status, headers, body)
-   responses = responses + 1
+--function response(status, headers, body)
+--   responses = responses + 1

 function done(summary, latency, requests)
    for index, thread in ipairs(threads) do
$ ./wrk -c 4 -t 2 -d 60 --timeout 300 -s scripts/setup.lua
thread 1 created
thread 2 created
Running 1m test @
  2 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.14s   824.71ms   6.39s    81.08%
    Req/Sec     1.69      3.42    10.00     86.89%
  74 requests in 1.00m, 76.44GB read
Requests/sec:      1.23
Transfer/sec:      1.27GB
thread 1 made 43 requests and got 0 responses
thread 2 made 36 requests and got 0 responses

Without script

$ ./wrk -c 4 -t 2 -d 60 --timeout 300
Running 1m test @
  2 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.39s     1.26s    6.52s    79.10%
    Req/Sec     0.80      2.22    10.00     93.94%
  67 requests in 1.00m, 68.88GB read
  Non-2xx or 3xx responses: 1
Requests/sec:      1.12
Transfer/sec:      1.15GB


Is it possible to make a benchmark with some payload which is sends as chunked request?

It is possible I may be misunderstanding the purpose of wrk.thread:stop(). When all of the threads have called stop(), the load test continues running.


local counter = 0
function setup(thread)
  thread:set("id", counter)
  print("Setup", counter)
  counter = counter + 1

function response()
  counter = counter + 1
  if counter == 100 then
  return wrk.format()

Run with wrk -t 4 -c 20 -d 60s -s ./wrk.lua [URL]


Setup	0
Setup	1
Setup	2
Setup	3
Running 1m test @
  4 threads and 20 connections
0	done
1	done
2	done
3	done <-- this is reached almost instantly (server is just a ping endpoint)
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    27.12ms    8.56ms  89.12ms   91.75%
    Req/Sec   179.75     37.38   222.00     90.00%
  400 requests in 1.00m, 83.59KB read <-- load test continued for whole duration
  Non-2xx or 3xx responses: 400
Requests/sec:      6.67
Transfer/sec:      1.39KB

(arrows added for comment)

Even though all threads have called wrk.thread:stop() the load test continues for the whole duration.

Is there any plan to support HTTP/2 in near feature ? if not, is there any recommendation for HTTP Benchmarking tool that support HTTP/2 ?

Hi all,

I am just trying out lua today for the first time, so apologize if this is
answered already, but I could not find the answer yet. Is there a way
to do something like:

for iteration in 1 to 100
make 'n' requests

directly via lua instead of writing a bash script to do the same and add
numbers, etc? Preferably the loop should be infinite and the test should
run for the time specified in '-d' option.

Thanks in advance.

1 threads and 15 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     0.00us    0.00us   0.00us    -nan%
    Req/Sec     0.00      0.00     0.00      -nan%
  Latency Distribution
     50%    0.00us
     75%    0.00us
     90%    0.00us
     99%    0.00us
  0 requests in 10.02s, 0.00B read
Requests/sec:      0.00
Transfer/sec:       0.00B

I want to make some test of 2000 users enter run specific url at the same time.
But i am afraid i have some confusing between connections and threads.

As i see it i need to run 2000 connection, if so, what the rule of thread here ?

Many thanks for your help, but the way, Amazing JOB.

Hi, how to compile this under Windows (x64) platform?

👋 After the license update per this commit, the software is not properly OSS licensed. Can you consider reverting that commit?

cc @wg @jimjag @leo-lb

I would love to see an example of how to use custom headers at the command line.

./wrk -H "Authorization:Basic 4525j24k532ktwklt" http://localhost...

doesn't seem to work.

wrk.method = "POST"
wrk.body   = '{"jsonrpc":"2.0","method":"cita_sendTransaction","params":["abcd"],"id":2}'
wrk.headers["Content-Type"] = "application/json"

Not support "application/json" post, it taken it as get method.

While I changed it to "application/x-www-form-urlencoded", the method is right.