Nginx (pronounced “engine x”) is a powerful and versatile web server renowned for its high concurrency, exceptional performance, and efficient memory utilization. Beyond serving static content, Nginx excels as a reverse proxy server for various protocols including HTTP, HTTPS, SMTP, POP3, and IMAP. It also functions effectively as a load balancer, distributing traffic across multiple backend servers, and as an HTTP cache, reducing server load and improving response times. This guide delves into key configuration parameters for optimizing Nginx performance.

Understanding Nginx Configuration for Performance

Nginx performance tuning involves carefully adjusting several key configuration directives. These settings control how Nginx utilizes system resources, manages connections, and handles requests. Let’s explore some of the most critical parameters:

worker_processes: Defining the Number of Worker Processes

The worker_processes directive dictates the number of Nginx worker processes that will be spawned. Each worker process operates independently, handling client requests concurrently. A general rule of thumb is to set this value to match the number of CPU cores available on your server. This allows Nginx to fully utilize the available processing power.

Setting worker_processes to auto automatically configures the number of worker processes to match the CPU core count. However, in scenarios involving significant disk I/O operations, increasing the number of worker processes beyond the core count might be beneficial.

To determine the number of processors on your system, execute the following command in your terminal:

grep processor /proc/cpuinfo | wc -l

Current Configuration:

worker_processes auto;

worker_connections: Maximizing Concurrent Connections

The worker_connections directive sets the maximum number of simultaneous connections that each worker process can handle. For high-traffic websites and applications, increasing this value can significantly improve performance. The default value is typically 768.

Theoretically, the maximum number of clients Nginx can handle is calculated as: worker_processes * worker_connections.

For optimal performance under heavy load, consider increasing the worker_connections value.

Example:

worker_connections  10240;

With the configuration shown above we have increased number of connections to 10240.

worker_rlimit_nofile: Increasing the File Descriptor Limit

The worker_rlimit_nofile directive allows you to increase the maximum number of files that each worker process can open. This is particularly important for applications that serve a large number of static files or maintain numerous open connections.

This directive is not present by default in the Nginx configuration file. You can add it to the main section of /etc/nginx/nginx.conf (below the worker_processes directive).

Example:

worker_rlimit_nofile 100000;

This configures the maximum number of open files to 100,000.

keepalive_requests: Optimizing Persistent Connections

The keepalive_requests directive specifies the number of requests a client can make over a single keep-alive connection. Keep-alive connections reduce latency by allowing multiple requests to be sent over the same TCP connection, avoiding the overhead of establishing a new connection for each request.

The default value is 100. A higher value can be beneficial, especially during testing or when using load generation tools that send many requests from a single client. However, for production environments, it’s crucial to find a balance that optimizes performance without consuming excessive server resources.

Example:

# Use this value for testing; comment it out when done.
keepalive_requests 20480;

access_log: Buffered Logging for Performance

The access_log directive defines the location and format of the Nginx access log. Writing log data to disk can be an I/O-intensive operation, potentially impacting performance. To mitigate this, buffering log writes can significantly improve efficiency.

By using the buffer parameter, Nginx accumulates log data in memory and writes it to the file in larger chunks, reducing the frequency of disk I/O operations.

Example:

access_log  /var/log/nginx/access.log  main buffer=10m;

This configuration buffers the access log writes in 10MB chunks.

Further Resources

For more in-depth information and advanced tuning techniques, explore the following resources:

  • http://www.slashroot.in/nginx-web-server-performance-tuning-how-to-do-it
  • https://rtcamp.com/tutorials/nginx/optimization/
  • http://nginx.com/blog/tuning-nginx/
  • https://www.digitalocean.com/community/tutorials/how-to-optimize-nginx-configuration