🎁 New User? Get 20% off your first purchase with code NEWUSER20 Register Now β†’
Menu

Categories

Nginx vs Apache: Choosing and Configuring Your Web Server

Nginx vs Apache: Choosing and Configuring Your Web Server

The Web Server Decision

Nginx and Apache together power over 60% of the internet. Both are excellent choices, but they excel in different scenarios. Understanding their differences helps you make the right choice and configure them effectively.

Architecture Comparison

Apache - Process-Based

Apache creates a process or thread for each connection:

  • MPM Prefork: One process per connection (compatible, memory-heavy)
  • MPM Worker: Threads within processes (balanced)
  • MPM Event: Async handling for keep-alive (modern, efficient)

Nginx - Event-Driven

Nginx uses an asynchronous, non-blocking architecture:

  • Single master process, multiple worker processes
  • Each worker handles thousands of connections
  • Lower memory footprint under load

When to Choose Each

Choose Nginx When:

  • Serving static content at scale
  • Acting as a reverse proxy or load balancer
  • Handling high concurrent connections
  • Memory efficiency is critical
  • Microservices or containerized deployments

Choose Apache When:

  • You need .htaccess file support
  • Running PHP with mod_php
  • Complex rewrite requirements
  • Shared hosting environments
  • Extensive module ecosystem needed

Nginx Configuration

Basic Server Block

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Reverse Proxy Configuration

upstream backend {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    keepalive 32;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        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 Connection "";
    }
}

Performance Tuning

# /etc/nginx/nginx.conf
worker_processes auto;
worker_connections 4096;

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1000;
    gzip_types text/plain text/css application/json application/javascript;
    
    # Caching
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
}

Apache Configuration

Virtual Host


    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
    
    
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    
    
    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined

Performance Tuning (MPM Event)


    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0

SSL/TLS Configuration

Nginx SSL

server {
    listen 443 ssl http2;
    server_name example.com;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    
    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;
}

Let's Encrypt Automation

# Install Certbot
apt install certbot python3-certbot-nginx

# Obtain certificate
certbot --nginx -d example.com -d www.example.com

# Auto-renewal test
certbot renew --dry-run

Security Hardening

Common Security Headers

# Nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Rate Limiting (Nginx)

http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
}

server {
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://backend;
    }
}

Monitoring

# Nginx status module
location /nginx_status {
    stub_status on;
    allow 127.0.0.1;
    deny all;
}

# Apache status

    SetHandler server-status
    Require ip 127.0.0.1

Conclusion

Both Nginx and Apache are production-ready web servers. Nginx excels at high concurrency and reverse proxy scenarios, while Apache offers flexibility and familiar configuration. Many organizations use bothβ€”Nginx as a frontend proxy with Apache handling dynamic content.

Our web server eBooks provide comprehensive configuration guides with real-world scenarios and advanced techniques.

Share this article:

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.