Linux – Using uWSGI’s built-in load balancer vs nginx

linuxload balancingnginxuwsgiweb-server

I have a python app that is exposed through wsgi and was going to deploy it to the world. There are no static assets that are served from it. The app will be deployed to a single machine. I am going to serve the wsgi app using uwsgi and could think of two options:

  1. serve through single uwsgi instance on machine, (figure out and twiddle with a good number of workers/processes to use maybe start out 2 * # cores)

  2. Run multiple uwsgi instances, each with a single worker, behind nginx on the same machine.

  3. Run single uwsgi instance, behind nginx

One thing to keep in mind, is that the server is already behind a load balancer.

I would consider experimenting with #2 or #3 if I had static assets to serve. Because there are no static files, it seems like it is overkill.

In this case would there be any benefit to running uwsgi behind nginx? opposed to a single uswgi server with an appropriate number of workers?

Best Answer

The answer to this question heavily depends on your use case.

I don't know much about uWSGI, but I can't imagine any use case where it would be make sense to have several similar instances of it running on the exact same machine/vm since it is obviously designed for threading. Its just additional overhead. So #2 is not really an option (if your app has to be restart often, fix your code rather than using such a setup).

#3 sounds kinda useless now, but it is not. nginx is not a lot of overhead, it's performance and memory footprint is probably negligible in this case compared to the python app. It does impact latency, but again, this shouldn't matter for anything short of a RTS game server (and http isn't built for low latency anyway). The real problem is additional configuration and another point of failure. However, your app is far more likely to fail than a well tested, heavily used webserver, so it basically boils down on the configuration.

With this out of the way, here are some things to consider.

  • If this is a small web app where you don't expect more users than what a single server can handle without problems (i.e. your personal home page, the homepage of a small school), a single uWSGI is totally okay. Since uWSGI has its own load balancer, you'll have a fallback which can handle scaling for small instances (I'm not sure about large deployments however).
  • If you are sure you app is gonna stay where its hosted now (i.e. AWS), you can still use #1 and use the hosters built-in load balancer. This reduces your overhead and you don't have to worry about additional configuration. You should however be aware that pricing and service may change and small hosters can go out of business (with AWS this risk is small enough).
  • If you think that your app may scale quickly out of a single VM and your hosters load balancer is no assurance, you should really add nginx. As I stated above it is not much of an overhead and if you suddenly need a second VM you will be very grateful. It also allows to handle crashes of you app and filter requests (for example if you're under DOS). If you're adding https, nginx will help you, too.

TL;DR

If you're sure that your app is not gonna scale quicker than you can scale the code (or not going to scale at all), that you don't need its additional features (your app is not as stable as you think it is!) and you're sure of your hosters load balancing capability, skip nginx. If not or if you're not 100% sure that above will stay true, use nginx. Its not much overhead but may save you a lot of trouble.