Nginx y Apache son los servidores web mas desplegados del mundo.
Arquitectura
La diferencia arquitectonica fundamental determina el rendimiento.
Apache: Basado en procesos/hilos
Apache utiliza arquitectura MPM.
Apache Architecture (Process/Thread Model):
Master Process
├── Worker Process 1
│ ├── Thread 1 → handles connection A
│ ├── Thread 2 → handles connection B
│ └── Thread N → handles connection C
├── Worker Process 2
│ ├── Thread 1 → handles connection D
│ └── Thread N → handles connection E
└── Worker Process N...
MPM Modes:
- prefork: 1 process per connection (safe for non-thread-safe modules like mod_php)
- worker: threads within process pool (more efficient)
- event: listener thread for keep-alive (best for Apache 2.4+)Nginx: Orientado a eventos
Nginx utiliza arquitectura asincrona orientada a eventos.
Nginx Architecture (Event-Driven):
Master Process (reads config, manages workers)
├── Worker Process 1 (single thread, event loop)
│ └── Event Loop: handles 1000s of connections via epoll/kqueue
│ ├── Connection A (non-blocking I/O)
│ ├── Connection B (non-blocking I/O)
│ ├── Connection C (non-blocking I/O)
│ └── ... (thousands more)
├── Worker Process 2 (single thread, event loop)
│ └── Event Loop: handles 1000s more connections
└── Worker Process N (typically = CPU cores)
Key: No thread-per-connection overhead
Result: 10K+ connections with ~30-50MB RAMBenchmarks de rendimiento
Depende del tipo de carga.
| Metrica | Apache 2.4 | Nginx 1.27 |
|---|---|---|
| Archivos estaticos | ~15.000-25.000 | ~50.000-100.000 |
| Conexiones simultaneas | Degradacion | Estable |
| Memoria | ~300-600MB | ~30-50MB |
| PHP | mod_php/PHP-FPM | PHP-FPM |
| Reverse proxy | Bueno | Excelente |
| SSL/TLS | Bueno | Excelente |
Comparacion de configuracion
Enfoques fundamentalmente diferentes.
Apache: .htaccess
Configuracion distribuida via .htaccess.
# Apache Virtual Host Configuration (/etc/apache2/sites-available/example.conf)
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example/public
<Directory /var/www/example/public>
AllowOverride All
Require all granted
Options -Indexes +FollowSymLinks
</Directory>
# Enable mod_rewrite
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# PHP via mod_php (prefork MPM required)
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
# Or PHP via PHP-FPM (recommended with event MPM)
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
# Logging
ErrorLog ${APACHE_LOG_DIR}/example-error.log
CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>
# .htaccess file (per-directory, no restart needed)
# /var/www/example/public/.htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]Nginx: Configuracion centralizada
Archivos de configuracion centralizados.
# Nginx Server Block (/etc/nginx/sites-available/example.conf)
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example/public;
index index.html index.php;
# SSL
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;
# Static files with caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# PHP via PHP-FPM
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
# SPA fallback (equivalent to .htaccess rewrite)
location / {
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
access_log /var/log/nginx/example-access.log;
error_log /var/log/nginx/example-error.log;
}Comparacion de funciones
Feature Apache 2.4 Nginx 1.27
-------------------------------------------------------------------
Module System Dynamic (load at runtime) Static + dynamic (since 1.9.11)
.htaccess Full support Not supported
URL Rewriting mod_rewrite (regex) rewrite directive (simpler)
Reverse Proxy mod_proxy + mod_proxy_http Native proxy_pass
Load Balancing mod_proxy_balancer Native upstream module
Caching mod_cache Native proxy_cache + FastCGI
WebSocket mod_proxy_wstunnel Native support
HTTP/2 mod_http2 Native
HTTP/3 (QUIC) Experimental Native since 1.25.0
Scripting mod_lua OpenResty (Lua), njs (JS)
Config Reload Restart required Graceful reload (zero downtime)
Per-dir Config .htaccess (runtime) Not available
License Apache 2.0 BSD 2-ClauseCasos de uso
Elegir Nginx:
- Alto trafico
- Reverse proxy
- Load balancing
Elegir Apache:
- Hosting compartido
- WordPress/PHP
Usar ambos
Nginx como reverse proxy delante de Apache.
# Nginx as reverse proxy in front of Apache
# /etc/nginx/sites-available/example.conf
upstream apache_backend {
server 127.0.0.1:8080; # Apache listens on port 8080
}
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;
# Nginx serves static files directly (fast)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
root /var/www/example/public;
expires 30d;
access_log off;
}
# Dynamic requests go to Apache (PHP, .htaccess)
location / {
proxy_pass http://apache_backend;
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;
}
}Configuracion de reverse proxy
# Nginx reverse proxy to Node.js / Python / Go backend
upstream app_servers {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
server {
listen 443 ssl http2;
server_name api.example.com;
location / {
proxy_pass http://app_servers;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}Load balancing
# Nginx Load Balancing Strategies
# Round Robin (default)
upstream backend_rr {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
# Weighted Round Robin
upstream backend_weighted {
server 10.0.0.1:8080 weight=5; # gets 5x traffic
server 10.0.0.2:8080 weight=3;
server 10.0.0.3:8080 weight=1;
}
# Least Connections
upstream backend_least {
least_conn;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
# IP Hash (sticky sessions)
upstream backend_ip {
ip_hash;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
# Health checks and failover
upstream backend_health {
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.3:8080 backup; # only used when others fail
}Configuracion SSL/TLS
# Nginx SSL/TLS Best Practices (2026)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# Modern TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
# Session resumption
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# HSTS (15768000 seconds = 6 months)
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
}Comparacion de seguridad
Ambos tienen buenos registros de seguridad.
Security Aspect Apache Nginx
-----------------------------------------------------------------
CVE History More CVEs (larger surface) Fewer CVEs (smaller codebase)
.htaccess Risk Can expose config errors N/A (no .htaccess)
Default Config Permissive Restrictive
Module Surface Large (many loaded) Minimal (compile what you need)
Rate Limiting mod_ratelimit limit_req / limit_conn (native)
WAF Integration mod_security (mature) ModSecurity + NAXSI
Access Control .htaccess / <Directory> allow/deny directives
Request Size Limits LimitRequestBody client_max_body_sizePreguntas frecuentes
Es Nginx mas rapido?
Para contenido estatico si. Dinamico similar.
Puede Nginx reemplazar Apache?
En la mayoria de casos si.
Cual para WordPress?
Apache tradicional, Nginx mas rapido.
Nginx como reverse proxy de Apache?
Patron popular y efectivo.
Caddy y Traefik?
Alternativas para casos especificos.
Herramientas y guias relacionadas
- JSON Formatter - Format Nginx/Apache JSON configs
- JSON to YAML Converter - Convert config formats
- Regex Tester - Test URL rewrite patterns
- Nginx Config Examples
- Nginx Location Block Regex Guide
- .htaccess Redirect Cheat Sheet
- DNS Record Types Guide