Deploying Python webapps with uWSGI

By March 21, 2013Technical

If you’ve deployed a number of WSGI apps like Moin and Django in your time, you’re probably familiar with Gunicorn. Like Unicorn for Rack/Rails apps, from which it borrowed the overall design philosophy, it’s straightforward, lightweight and performant.

Make no mistaken, Gunicorn does a great job, but there’s a new kid on the block: uWSGI.

We’re starting to roll out uWSGI in favour of Gunicorn, so we thought we’d share some of the thinking behind this and what the benefits are.

Let’s briefly cover what Gunicorn and uWSGI have in common: They’re both containers that’ll serve up a WSGI app, providing an HTTP connector that a frontend webserver can proxy requests to. This is similar to using mongrel/thin/unicorn for Rails apps, and is very flexible because any frontend webserver (we use apache and nginx) can proxy requests to the app container.

This is a boon for busy sites because the webserver and appserver tiers can be scaled independently of each other, as necessary. Need to offload SSL termination and load-balancing? You can do that.

uWSGI was designed with a tight set of core goals in mind: versatility, performance, reliability and having a small resource footprint. For us, performance is probably the headline feature. We specialise in managing large-scale deployments, and being able to squeeze more performance out of our customers’ applications is always welcomed. uWSGI is written in C and comes with a list of tunable options longer than a Java stacktrace.

Second to this for us is manageability. One of the nice things about being written in C is that uWSGI is easy to roll out as a native distro package. Gunicorn is usually distributed as a Python package, which seems convenient, but is subject to the vagaries of different python environments – do you install it systemwide? In a virtualenv per user? What about updates? Independence is a good thing to have. uWSGI is small, and it just works.

Another of uWSGI’s handy features is monitoring. Using the --stats config option exposes metrics as a JSON blob through a dedicated monitoring socket. This works very nicely with our comprehensive monitoring systems, and makes it easy to extract and graph the available data.

As a final point of interest, uWSGI introduces a new connector protocol, confusingly called uwsgi (all lowercase). This is provided as an alternative to HTTP proxying between the webserver and application, allowing for out-of-band flexibility and higher performance compared to HTTP – similar to FastCGI. nginx was the first webserver to support uwsgi, and there now appears to be modular support for Apache as well.

So that’s uWSGI in a nutshell. It really aspires to be much more than just a simple replacement for Gunicorn, but it does a fantastic job at that too. It’s definitely worth checking out, even for little apps.

Leave a Reply