🎁 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:

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:
Even R. Whitlock
About the Author

Even R. Whitlock

Enterprise IT Administration, Microsoft Technologies, Infrastructure Automation, Technical Documentation

Evan R. Whitlock is an IT professional and technical author focused on enterprise system administration, cloud-based services, and secure infrastructure design.

He has extensive experience working with Microsoft technologies, including Windows Server, Active Directory, PowerShell automation, and cloud-integrated enviro...

Windows Server Active Directory PowerShell Microsoft Cloud Services Infrastructure Management

Stay Updated

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