Hi all, I've used wrk[0] to benchmark quark over a loopback interface.
With the latest code in git we have: $ ./wrk -t1 -c200 -d30s http://127.0.0.1 Running 30s test @ http://127.0.0.1 1 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.57ms 9.15ms 1.60s 99.91% Req/Sec 16.66k 2.16k 22.07k 65.87% 482946 requests in 30.00s, 6.53GB read Socket errors: connect 0, read 0, write 0, timeout 29 Requests/sec: 16098.15 Transfer/sec: 222.93MB $ ./wrk -t4 -c200 -d30s http://127.0.0.1 Running 30s test @ http://127.0.0.1 4 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 847.56ms 1.27s 3.26s 81.00% Req/Sec 1.60k 1.49k 6.69k 51.82% 197048 requests in 30.05s, 2.66GB read Socket errors: connect 200, read 0, write 0, timeout 1338 Requests/sec: 6558.11 Transfer/sec: 90.82MB Obviously these numbers do not mean anything unless compared to some other http server implementation. >From some quick testing that me and Hiltjo did yesterday, we found that nginx is twice as fast. That's ok, quark has no optimizations in place and can easily serve a few thousands of clients with static content. Quark uses fork() internally to handle the clients. I think that's a bless in disguise. Any other technique (select, poll, epoll, etc.) will require some small finite state machine to keep track of the connections, recycle the appropriate file descriptors etc. More specific interfaces like sendfile(), epoll() etc. are also going to cause problems with portability. I recommend sticking with fork() for now until we really really have to move on to something else. I will be looking at a poll() based implementation soonish to see how it performs versus the complexity. I will post a patch here if I have something worthwhile. [0] https://github.com/wg/wrk