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.