http4k: Http4k-netty performs really badly on all benchmarks (with lots of errors)

I’ve checked the techempower benchmarks and it seems that http4k-netty performs really badly and has a lot of errors in the benchmarks. Is this an inherent problem with Netty or is the benchmark bad?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17 (8 by maintainers)

Most upvoted comments

As an aside, it might also be worth testing the old apache engine (http4k-server-apache4) and the sunhttp engine that comes with core, just to see how they compare. I’ve a suspicion that apache4 might outperform apache5… upside_down_face

Here you go: https://storage.googleapis.com/strohel-pub/bench-http4k-server-engines-excerpt/bench-results.html

  • SunHttp is definitely usable just for development (how can it always have > 40 ms latency when the endpoint handling itself if < 2 ms?)
  • apache4 seems to be a tiiiiny bit faster than apache (5), both have some high memory consuption under load issues (I’ll open separate issue)

Cool, tried it now and I can confirm that the TCP connection is now persistent (netty even adds connection: keep-alive header) and wrk is not fooled anymore. Let me run more representative and lengthier benchmarks and report the results.

the easiest thing is to just copy the entire netty.kt file from the branch into your project and use that version inside the call to asServer()

I was able to reproduce http4k-netty benchmark problems on a different http4k microservice and my own benchmarking testbed that also uses wrk (HTTP load generator).

When looking at the traffic using Wireshark, I can see that server responses on netty have Connection: close header and no Content-length header (which is a probable cause of the Connection: close). All other tested server engines behave differently and more efficiently: they do serve Content-length header and keep the TCP connection open for next requests.

In addition to hurting performance, this seems to fool wrk’s hand-written HTTP parser into reporting read errors for every request (even though the HTTP response seems correct to both me and Wireshark):

$ wrk -c1 -t1 -d1 --latency --timeout=15 'http://localhost:8080/city/v1/get?id=101748111&language=cs'
Running 1s test @ http://localhost:8080/city/v1/get?id=101748111&language=cs
  1 threads and 1 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.38ms    0.93ms  12.12ms   95.33%
    Req/Sec   289.45     33.24   330.00     81.82%
  Latency Distribution
     50%    3.21ms
     75%    3.51ms
     90%    3.82ms
     99%    8.65ms
  317 requests in 1.10s, 56.96KB read
  Socket errors: connect 0, read 317, write 0, timeout 0
Requests/sec:    288.12
Transfer/sec:     51.77KB

Perhaps there is something in the Http4k <-> Netty integration that prevents content-length from being correctly passed?

(Netty itself seems to be well capable of persistent connections when used by Ktor) CC @goodhoko.

Hah, that’s funny. I know Gyula personally. I think I’ll just talk to him. 👍 I guess you are right. The article I linked was about Netty (which is problematic apparently 😃 ).