Home | Articles | CV (pdf | short)
<2012-09-02> by Lorenzo

Tornado vs. Warp vs. Yesod

Today I tried to benchmark 3 web servers that I've used recently:

  1. Tornado
  2. Warp
  3. Yesod

In fact, these are only 2 web servers, because Yesod runs on top of Warp and it's a fully fledged web framework, rather than a web server: but this was also the intent of the benchmark, i.e. to measure how slower all its goodies made Yesod with respect to Warp.

Tornado and Warp are obviously very different web servers (async vs. threaded, interpreted vs. compiled, etc.) but, who cares?

The benchmark is very simple: a single handler returning "Hello World", very original. Obviously, this is hardly a real world example, but it can give indications even if only with "orders of magnitude" of approximation.

Nonetheless, the results were very interesting. First of all, here is the code.

Tornado

Warp

Yesod

And the results, obtained using httperf:

$> httperf --hog --client=0/1 --server=localhost --port=8080 --uri=/ --rate=1000 --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=100 --burst-length=20
Framework req/s
Tornado 518
Warp 10079
Yesod 929
Yesod w/o session management 7924

Wait! What?! Yesod is 10 times slower than Warp!?

I asked an explanation to the Yesod developers and they tracked down the issue: the work of these guys is an example worth studying of how to benchmark and debug code! Anyway, it looks like the issue is that serializing timestamps is incredibly inefficient: I hope a patch will be ready soon! In the meantime, I strongly suggest you to disable session management from Yesod if you want high performance. (In the code shown, I've also disabled Hamlet, Yesod's templating system, but it turned out that it didn't make much difference: code using Hamlet is in gist.)

Overall, though, even on my crappy single-core old laptop, the result is amazing: Warp/Yesod is ~20 times faster than one of the fastest Python web servers.