How to optimize your Nginx server in terms of the number of requests/trafics processed simultaneously in your web app ?

Orpheric ALLAGBE
4 min readApr 10, 2024

Context: You have your web application or your SaaS solution running on the cloud using the popular NGINX server. And according to your data you have a server with four (04) cores in its CPU with an average of 4000 simultaneous user connections.
Your application being scalable and responding to a highly demanded need, you go from 4000 active users to almost 10,000 or even 100,000 users. Consequence: more gains but also and above all INCREASED PERFORMANCE PROBLEMS or SLOW CONNECTIONS to your server and consequently to your web application.

In the remainder of this article, we will quickly try to resolve this performance problem on our NGINX server. Here we go !

Consider the snippet of code from the NGINX configuration file: nginx.conf located at /etc/nginx/nginx.conf.

user www-data;
worker_processes auto;

events {
worker_connections 1024;
}

Here, “worker_processes” controls the number of worker processes that can use NGINX. Its value is generally equal to the number of CPU processors available on our server. The “auto” attribute does this automatically in our case.

“worker_connections” defines the number of connections that a worker process can open. To find its value, type in the command: ulimit -n. The latter gives us the number of file descriptors that a worker process can open under Linux. It is often 1024.

To summarize, considering the problem posed in our context at the top of this article, if your server has (04) cores in your CPU and you define “work_connections” to 1024 based on the value returned by “ulimit -n” of course, this means that your NGINX server can handle 4096 (1024 * 4) connections (users) at the same time, simultaneously.

So, if the 4097th user arrives, his connection will be placed in a queue, and will be served only when NGINX has some space to breathe. Otherwise, the connection of 4097 ieme will be almost slow.

Let’s assume that you have just realized through the figures that your application is now holding traffic of almost 100,000 connections, which has led to performance problems and incessant complaints from users. We will try to resolve this.

Warning: if you do not have high traffic peaks or performance problems, we do not recommend that you make all of the settings that follow. This is for the good of your cloud server infrastructure.

You probably remember “ulimit -n”, this command which allowed us to know the value assigned to “worker_connections”. In reality, “ulimit -n” sets the soft, default limit of connections that a worker process can open.
And if there is a soft limit, there must be a stricter limit somewhere, right? This brings us back to “ulimit -Hn” which defines the strict and REAL limit of connections that a process can open.

The “ulimit -Hn” command gives us 1,048,576 in our case. The soft limit, by default being only 1024, we can therefore easily upgrade or bypass to have a number allowing us to better manage the excess of incoming traffic.

Considering the strict limit and in order to fill the surplus of simultaneous traffic going from 4000 to 100,000 or so, we had the following configuration

user www-data;
worker_processus auto;
worker_rlimit_nofile 25000;

events {
worker_connections 25000;
}

You would have noticed that we had a slight upheaval in the new code. “worker_rlimit_nofile” defines the maximum number of file descriptors in our system. Its value therefore corresponds exactly to that of “ulimit -n” corresponding to the default soft limit of connections that a SINGLE process can open.

For a quick calculation, if in our case we wanted our server to be able to process 100,000 user connections simultaneously, we will need a process to be able to process 25,000 connections alone due to (04) process cores on our server.
Which gives us: “worker_rlimit_nofile === ulimit === 25000

Our strict limit being 1,048,576 per process we can therefore validly afford to be satisfied with 25,000 connections per process (04) or the 100,000 sought.

NB1: IT IS IMPORTANT TO NOTE THAT A SETTING OF “work_rlimit_nofile” TOO HIGH can cause performance problems even if the server does not have enough resources to handle the load.

NB2: ONLY MODIFY THIS WHEN YOU EXPERIENCE REAL TRAFFIC PEAKS OR PROBLEMS.

THANKS ! I hope you enjoyed this article.
Don’t hesitate to leave me a comment if you have any concerns.

Signed Orphéric.
I’m Laravel Software Developer and Data Infrastructure Engineer

--

--

Orpheric ALLAGBE

Hello ! 🙌🏾 I'm Orpheric. Laravel Software Developer and Data Infrastructure Engineer. I write about software environment with Laravel ecosystem, AI and Data.