gevent: gunicorn vs uWSGI
Following my previous benchmark I finally got around to benchmarking uWSGI with gevent and comparing its performance to gunicorn with gevent worker type. To do this you have to compile uWSGI and gevent from source, so I used the latest tagged releases at the time of the test, uWSGI 1.3 and gevent 1.0b4.
As it turns out, performance of the two servers is almost identical when using gevent...
I initiated the system exactly the same way as the last test, except for instead of installing uWSGI from pip I did it from their new github repo. I followed the guide in their wiki http://projects.unbit.it/uwsgi/wiki/Gevent for compiling uWSGI:
git clone git://github.com/unbit/uwsgi.git cd uwsgi git checkout 1.3 python uwsgiconfig.py --build gevent sudo cp uwsgi /usr/local/bin/
I also had to install gevent from source as uWSGI only works with gevent 1.0+ and it's still in beta (and thus not on pypi):
# cython needed for gevent sudo apt-get install cython git clone git://github.com/SiteSupport/gevent.git cd gevent git checkout 1.0b4 sudo python setup.py install
After this you'll be able to run uwsgi with gevent loop engine ( --loop gevent parameter )
uwsgi -s 127.0.0.1:8001 --processes 4 --loop gevent --enable-threads --async 128 --disable-logging --wsgi-file greq.py
To see asynchronous performance increase for uWSGI, you need to actually use gevent in your application code. This is different from the way that gunicorn handles it as it would do all of that for you at the request level. I used grequests instead of requests, which wraps around requests with gevent.spawn when testing uWSGI. Doing this in gunicorn would actually result in slightly lower performance.
import grequests def application(environ, start_response): status = '200 OK' r = grequests.get('http://10.1.1.2') r.send() output = r.response.content response_headers = [('Content-type', 'text/html'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]
Just like the last test, I used ab and tested at multiple concurrency levels. Results are below:
As you can see, the results are pretty close with uWSGI having a slight edge in throughput in some cases and gunicorn having a slight advantage in request times. I think we can safely conclude that most of the work is being handled by gevent in this benchmark, so the server doesn't actually play a huge role in performance. That being said, gunicorn is a lot easier to install as it doesn't need manual compilation or beta versions of gevent.
Posted Sun 14 October 2012 by Ivan Dyedov in Python (Python, WSGI, gevent, gunicorn, uWSGI, benchmark, nginx, Ubuntu, Linux)