Lighttz – a simple and fast web server

Update : A naive implementation of using Lua 5.1 to generate a dynamic response has been added. This loads Lua, loads a Lua script and executes it. Retrieves the string response and returns it to the browser. Take a look below for a new additional download link.


There are many well written , fast web servers around with full features for CGI , FastCGI , proxying and dynamic language support such as Ruby, PHP and Python. So what is Lighttz ? It’s a small HTTP server written in C , benchmarked against the big guns. It is by no means a replacement for the big four, and is mainly a testing showcase. For the sake of brevity, the comparison of the first benchmarks will compare the following web servers:

  • Apache/2.2.8-mpm-prefork
  • lighttpd/1.4.19
  • nginx/0.5.33
  • userver-0.6.0 – compiled and run with epoll support
  • lighttz/0.1 – libev epoll event model

Short summary and the configuration as tested is below. Please note that other event models such as select and poll are available under each server , but these were picked for the performance or wide use ( in case of Apache ) .

Apache –

The usual pre-forking server most, widely used to power many websites.

Lighttpd –

Also a very popular server. Instead of a forking model, it utilizes a fast a very well performing epoll mechanism.

Nginx –

A little younger but equally fast server , which also utilizes epoll event model.

Userver –

A small, microwebserver that’s mostly used for tests and benchmarks. Project is maintained at University of Waterloo.

Lighttz –

A short C program that simulates an HTTP server and handles the requests using Libev and epoll.

Test platform

Ubuntu 8.04 , Kernel 2.6.24-16 SMP , 2GB RAM, Core2Duo 2.4GHz

Benchmarking Client Program

ApacheBench . Command used:

ab -c1000 -n1000000 <host:port> . The test document index.html is a 357 byte static file. Lighttz did not use the static file, it sent out the exact same contents as index.html contained in a char array.

The above simulated 1000 concurrent clients making 1000000 requests .


Each result is an average of three runs with one pre-warming run to let each server utilize the cache.

Requests per second. Listed in order of fastest to slowest.

  1. Lighttz – 14,719 ( Cpu usage: 40-50% , Memory: 188 KB , 1 process )
  2. Lighttpd – 14,701 ( Cpu usage: 65-85%, Memory: 6.6 MB , 1 process )
  3. Nginx – 14,378 (Cpu usage: 65-80%, Memory: 2.1 MB , 2 processes )
  4. Userver – 13,221 ( Cpu usage: 75-90%, Memory: 1.2 MB, 1 process )
  5. Apache – 9,512 ( Cpu Usage: 60-80%, Memory: 3.5 MB x 147 processes , 514 MB total )

Hardware used, other running servers and operating systems will reflect different results. The tests were not run to define maximum performance for all solutions. Each application will apply a different level of stress on the server.

Source code for Lighttz :

Lua version:

Libev :

Index.html file was taken from article located here:

18 responses to “Lighttz – a simple and fast web server

  1. Could you help me compiling lighttz.c?

    gcc -o”lighttz” ./lighttz.o -lev

    returns an error

    /usr/bin/ld: can’t found -lev
    collect2: ld returned 1 exit status

  2. Joshua, that is a linker error.
    1. You have to install libev . Download the latest source code for LibEv , do a makefile compile and install .

    The linker should then find the compiled libev in your lib folder. Depending on the system , it may be located in : /usr/local/lib

    The compiled .so shared object will be found when given the -lev flag at compile time .

    If you encounter errors with dynamic linking, you can set a search path to the directory where your libev resides. Let’s say that it is in /usr/local/lib . You could tell the linker to search that directory by typing this in command line:

    export LD_RUN_PATH

    Arek Bochinski

  3. gcc -LLIBDIR -o lighttz lighttz.c -lev

    I should use “-LLIBDIR” flag, else:

    [cocobear@cocobear Download]$ ./lighttz
    ./lighttz: error while loading shared libraries: cannot open shared object file: No such file or directory

  4. I just tried Lighttz, and it gave some pleasingly fast results using ab. However, I tried using HTTPerf to test the output, and it would only return as many requests as the –num-conns=X option. e.g. if you set –num-conns=5, you get 5 2xx responses, then it quits.

    Do you know why this happens? Does it have something to do with not closing connections properly?


  5. I get the feeling the issue is related to TCP Keepalive, which I think HTTPerf uses automatically. I’ve been trying to add Keepalive support to lighttz, but can’t seem to get it working. (setsockopt…)

    Any ideas?

  6. I didn’t try nginx on linux jet, but but on freebsd it is really efficient. I couldn’t ever get it to use more than 10% cpu (user) without keep-alive.

    Some hints about your testing:

    nginx has a feature to serve an empty 1×1 transparent gif from memory. the other servers might have memory caching or similar capabilities making the comparison more interesting.

    apache is probably not interesting at all for a comparison, because it’s architecture is focused on hosting “low-tech” scripting engines like php, which has quite different needs.

    user cpu usage would be interesting to report, as we want to know how much time is spent in the application code.

    thttpd would be an interesting candidate to compare against, as it also doesn’t support keep-alive requests.

  7. Pingback: links for 2009-10-27 | 孩子气-孙秀楠宝宝 | C++, Lua, 技术爱好者

  8. Interesting.

    Recently I was experimenting on “fapws” which is also based on libev, and I was really impressed. I’ll be going to check your’s as well very soon.

    My query is that, does it support any dynamic language support such as python/perl/php or fastcgi ?

  9. Pingback: 可可熊的窝 » Blog Archive » libev编译篇

  10. Maybe you should also include g-wan in your tests and check against it as well. It’s a very tiny webserver with a great performance…….check it out at…..i’m sure you will be surprised………

    • Hi Kailash,

      When I was doing the testing, Gwan was not available. I think one of their developers saw this post and commented somewhere else on the site about Gwan.
      Our communication ended at that and I remember wanting to test it as well.

      Seeing that a pre-compiled binary is available for Linux systems, I will test it out, but it feels disingenuous to compare a closed source
      server to community code.

      The way I see it and I’m sure I am not alone in this, we are reaching limits of ‘good-enough’ performance without hindrance of closed source.

      On to Gwan,

      If I may call on the great developers there to open source it and provide us transparent access. There are many business models
      that might provide them with good revenue streams.

      • Hello Arek,

        I am curious to know your opinion about these to sentences that I am not sure to completely understand:

        “it feels disingenuous to compare a closed source
        server to community code”


        “we are reaching limits of ‘good-enough’ performance without hindrance of closed source”

        Please reply by email or if you choose to reply on your site put me in copy by email so I have a chance to read you.

        I would also be interested in to discuss your last statement “there are many business models
        that might provide them with good revenue streams”.

        Thanks you!


        PS: I forgot that wordpress is censoring my domain name (… so I am using another one for the email address.

  11. Wow freaking nice.. just googled for a easy/small libev sample..

    + I really wanted to have a little embedded HTTP-Server in my application ..

    Nice code 😉

  12. Looks Good !

    2 questions :

    1. Can’t compile the C file… could you provide precompiled bins ?

    2. Is the build in Lua interpreter blocking or non blocking ?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s