Skip to content
Faizul Karim Fahim

Nginx vs Apache Performance Tuning Guide

A practical sysadmin guide to Nginx and Apache configuration and performance tuning for production Linux servers.

Published 4 min read DevOps
Abstract digital illustration of server racks with glowing blue and orange data streams representing web server performance tuning.
On this page
  1. Nginx Configuration and Worker Tuning
  2. Optimizing Worker Processes and Connections
  3. HTTP Core and Keepalive Buffers
  4. Apache MPM Event Configuration
  5. Configuring MPM Event in Apache
  6. Reverse Proxy and Caching Best Practices
  7. Nginx Reverse Proxy Setup
  8. Conclusion

Mastering Nginx and Apache configuration is essential for any developer or sysadmin managing production Linux infrastructure. While both web servers power the majority of the modern web, their architectural differences demand completely different tuning strategies. Choosing the right settings prevents resource exhaustion, minimizes latency, and keeps your applications stable under heavy traffic spikes.

Whether you are scaling a single VPS or auditing a multi-node cluster, understanding how these servers handle memory, connections, and worker processes makes all the difference. Sometimes, optimizing infrastructure goes hand in hand with network diagnostics, much like troubleshooting local bottlenecks as detailed in our guide on why my 300 Mbps router shows only 144 Mbps on Wi-Fi. Let's dive into practical configurations for both web servers.

Nginx Configuration and Worker Tuning

Nginx uses an asynchronous, event-driven architecture designed to handle thousands of concurrent connections with minimal memory footprints. Tuning Nginx begins with the main configuration file located at /etc/nginx/nginx.conf.

Optimizing Worker Processes and Connections

The worker_processes directive should generally match the number of available CPU cores on your server. Setting this to auto lets Nginx detect the core count dynamically.

user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}
  • worker_rlimit_nofile: Increases the limit on maximum open files for worker processes, preventing the dreaded 502 Bad Gateway or too many open files errors.
  • worker_connections: Defines how many simultaneous connections each worker process can handle. Combined with worker_processes, this dictates your max client capacity.
  • use epoll: Forces the scalable Linux kernel polling method.
  • multi_accept: Allows a worker process to accept all new connections rather than one by one.

HTTP Core and Keepalive Buffers

To optimize throughput for web applications, adjust your HTTP block settings to reduce latency and drop slow clients.

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    client_body_buffer_size 128k;
    client_max_body_size 10m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;
}

Apache MPM Event Configuration

Historically, Apache relied on the Prefork Multi-Processing Module (MPM), spawning a separate process for every connection. Modern production environments should always use the Event MPM, which handles connections asynchronously similar to Nginx, making it vastly superior for high concurrency.

Configuring MPM Event in Apache

Open your MPM configuration file (typically /etc/apache2/mods-available/mpm_event.conf on Ubuntu/Debian systems) and adjust the threading parameters:

<IfModule mpm_event_module>
    StartServers             3
    MinSpareThreads          75
    MaxSpareThreads          250
    ThreadLimit              64
    ThreadsPerChild          25
    MaxRequestWorkers        400
    MaxConnectionsPerChild   10000
</IfModule>
  • MaxRequestWorkers: Limits the total number of simultaneous requests that can be served. Calculate this based on available RAM to avoid swapping.
  • ThreadsPerChild: Sets the number of worker threads created by each child process. Combined with MaxRequestWorkers, this defines your active process pool.
  • MaxConnectionsPerChild: Forces child processes to recycle after serving a set number of requests, preventing memory leaks in older modules.

Reverse Proxy and Caching Best Practices

A very common architecture deploys Nginx in front of Apache. Nginx handles static assets, SSL termination, and slow clients, while Apache processes dynamic backend code like PHP or Python.

Nginx Reverse Proxy Setup

Configure Nginx to pass dynamic traffic to Apache running on port 8080:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        root /var/www/html;
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}

Properly tuning your web stack also helps maintain overall uptime and system responsiveness, which is equally critical when optimizing environments for search indexing, as outlined in our guide on how to optimize website for Googlebot crawling.

Conclusion

Effective web server tuning is not a one-time task; it requires continuous monitoring of CPU utilization, memory consumption, and error logs under peak loads. By shifting Apache to the Event MPM, configuring Nginx worker processes correctly, and setting appropriate timeout and buffer limits, you can dramatically improve response times and server stability.

Frequently asked questions

Should I use Nginx or Apache for a high-traffic static site?

Nginx is generally preferred for high-traffic static content due to its event-driven architecture, which consumes significantly less memory under heavy concurrent loads.

Can Nginx and Apache run on the same server?

Yes, they frequently run together where Nginx acts as a reverse proxy handling incoming traffic, static files, and SSL termination, passing dynamic requests to Apache running on a backend port.

How do I test my web server configuration changes safely?

Always run validation commands before reloading services. For Nginx use 'sudo nginx -t', and for Apache use 'sudo apache2ctl configtest' or 'sudo httpd -t'.

// keep reading

Related posts

All blog posts