Nginx

The Nginx web server was design with the intent to solve the C10K problem, support 10.000 simultaneous connections. The Nginx software architecture describes how this goal was achieved.

This performance quality drives the design of the architecture which is rooted in an event system that processes the client request without blocking and using less resources. For instance, the Apache solution associates a process or a thread to each request, which results in a more simple programming model, and so less error prone, but that requires more resources, at least a thread per request being processed. That’s the reason for the C10K problem:

“To illustrate the problem with slow clients, imagine a simple Apache-based web server which produces a relatively short 100 KB response — a web page with text or an image. It can be merely a fraction of a second to generate or retrieve this page, but it takes 10 seconds to transmit it to a client with a bandwidth of 80 kbps (10 KB/s). Essentially, the web server would relatively quickly pull 100 KB of content, and then it would be busy for 10 seconds slowly sending this content to the client before freeing its connection. Now imagine that you have 1,000 simultaneously connected clients who have requested similar content. If only 1 MB of additional memory is allocated per client, it would result in 1000 MB (about 1 GB) of extra memory devoted to serving just 1000 clients 100 KB of content. In reality, a typical web server based on Apache commonly allocates more than 1 MB of additional memory per connection, and regrettably tens of kbps is still often the effective speed of mobile communications. Although the situation with sending content to a slow client might be, to some extent, improved by increasing the size of operating system kernel socket buffers, it’s not a general solution to the problem and can have undesirable side effects.”

Nginx does a better management of resources by allocating a single-threaded process per core which manages thousands of connections (schedule resources tactic). Therefore, the number of simultaneous requests it can process is nonlinear with the amount of memory it needs, it can process more requests using slightly the same amount of memory.

“Thus, the web server should be able to scale nonlinearly with the growing number of simultaneous connections and requests per second.”

On the other hand, there isn’t a bottleneck in terms of CPU because the main reason for the request processing time is transmission. However, the actual processing of the request can take longer, for instance the processing of a php page using the php module is not done by Nginx worker processes but it is delegated to a FastCGI process. Therefore, a common web server architectural topology is to use Nginx as a reverse proxy that dispatches requests to other web servers like Apache. Additionally, it is particularly fit to serve static content, which is quickly processed. To enhance its capabilities as a reverse proxy Nginx uses a file system cache.

Nginx more complex programming model, event-driven, is another reason why Apache is frequently used as a backend server due to the number of modules that are available.

“nginx module invocation is extremely customizable. It is performed through a series of callbacks using pointers to the executable functions. However, the downside of this is that it may place a big burden on programmers who would like to write their own modules, because they must define exactly how and when the module should run.”

Besides performance, Nginx also has the capability to dynamically restart its workers and even the master process. This is due to the fact that processing of requests is independent, which means that it is possible to simultaneously process requests using two different configurations. The master process can launch new workers according to a new configuration while the old workers finish processing their pending requests. Additionally, it is also possible to launch a new master while the old master finishes coordinating its workers, which allows a hot deployment of Nginx core modules. These capabilities give to Nginx the quality of runtime modifiability of configurations and runtime software upgrade. This may also have impact on availability because the deployment of a bug fix does not require downtime.