WordPress aguenta alto tráfego, mas só até você trombar nos gargalos clássicos. O problema é que eles quase nunca aparecem onde a galera imagina 😅
Vou listar os gargalos típicos, em ordem de impacto real em produção, com sinais claros e como confirmar cada um.
Otimizar Apache e PHP-FPM para WordPress de alto tráfego exige planejamento cuidadoso de infraestrutura e configuração do servidor. Muitas equipes só começam a ajustar esses parâmetros quando o site já apresenta lentidão ou indisponibilidade. Esse comportamento é típico de ambientes que operam de forma reativa. No guia sobre operação reativa vs operação proativa em servidores, explicamos como equipes podem evoluir para uma gestão mais estratégica da infraestrutura.
1️⃣ Banco de dados (MariaDB/MySQL) — o vilão nº 1
O que acontece
- Consultas lentas
- Locks em tabelas
- Muitas queries repetidas por página
Sintomas
load averagesobe mesmo com CPU “livre”IOWaitaparece sem disco saturado- Páginas específicas ficam lentas (home, busca, WooCommerce)
Causas comuns
- Plugins mal feitos (SEO, estatística, filtros)
- Falta de índices
innodb_buffer_pool_sizepequenoORDER BY RAND(),LIKE '%termo%'
Como confirmar
SHOW PROCESSLIST; SHOW ENGINE INNODB STATUS\G
2️⃣ PHP-FPM — fila invisível
O que acontece
O tráfego cresce → PHP não consegue atender → requisições ficam esperando.
Sintomas
- Tempo de resposta alto sem erro
502 / 504intermitente- CPU baixa, site lento
Causas comuns
pm.max_childrenbaixomax_execution_timealto demais- Scripts PHP pesados (Elementor + Woo + plugins)
Como confirmar
pm.status_path slowlog
3️⃣ Cache mal configurado (ou inexistente)
O que acontece
Cada visitante gera:
PHP → MySQL → PHP → HTML
em vez de servir HTML pronto.
Sintomas
- Site cai com picos pequenos
- Mesmo conteúdo recalculado sempre
- Home lenta, posts simples também
Causas comuns
- Cache só no plugin (sem cache real de página)
- Cache ignorado para usuários anônimos
- Sem OPcache
Stack ideal
- Cache de página (Nginx/FastCGI)
- OPcache
- Object Cache (Redis)
4️⃣ Plugins — efeito dominó
O que acontece
Um plugin ruim multiplica o custo de cada request.
Sintomas
- Lentidão após “só instalar mais um plugin”
- Queries duplicadas
- Admin lento
Campeões de problema
- Page builders
- Plugins de estatística
- Plugins de busca interna
- Plugins SEO mal configurados
Como confirmar
- Query Monitor
SAVEQUERIES- Slow log do PHP
5️⃣ Nginx / Apache — gargalo silencioso
O que acontece
Servidor web vira fila de espera.
Sintomas
- Muitas conexões abertas
- CPU ok, RAM ok, mas lentidão geral
netstatcheio
Causas comuns
- Apache sem proxy
KeepAlivemal ajustado- Worker insuficiente
Como confirmar
ss -s apachectl status nginx stub_status
6️⃣ Disco — mesmo NVMe sofre
O que acontece
WordPress escreve MUITO:
- Sessões
- Logs
- Cache
- Banco
Sintomas
IOWaitintermitente- Lentidão aleatória
- Pico ao mesmo tempo todo dia
Causas comuns
- Banco + site no mesmo disco
- Sem
noatime - Swap em SSD lento
Como confirmar
iostat -x
7️⃣ Tráfego externo: bots e crawlers
O que acontece
Bots consomem PHP e DB como usuários reais.
Sintomas
- Pico fora de horário
- User-Agents estranhos
- Googlebot “derruba” site
Causas comuns
- Sem rate limit
- Sem cache para bots
- XML sitemap pesado
8️⃣ Falta de separação de camadas
O erro clássico
“Tenho CPU e RAM sobrando, mas está lento”
O problema real
Tudo roda no mesmo lugar:
- Web
- PHP
- DB
- Cache
- Cron
Solução em tráfego alto
- DB separado
- Cache fora do PHP
- Cron real (não WP-Cron)
📌 Regra de ouro do WordPress em alto tráfego
Se o WordPress chega no PHP, você já perdeu desempenho.
Tráfego alto de verdade funciona assim:
Cache (HTML) → Cache de objeto → PHP → DB
Quanto menos requests chegam no PHP, melhor.
para cenário de alto tráfego real, não setup genérico de blog 🙂
Stack: Nginx (proxy) → Apache → PHP-FPM → MariaDB 11.3
Objetivo: máximo throughput, mínima latência, sem “engarrafamento invisível”
🧱 Arquitetura recomendada (fluxo ideal)
[ Cliente ]
↓
[ NGINX ]
├─ Cache HTML (FastCGI Cache)
├─ Rate limit / Bots
└─ Proxy → Apache
↓
[ Apache ]
└─ PHP-FPM
↓
Object Cache (Redis)
↓
MariaDB 11.3
👉 Meta: 90%+ das requisições morrem no Nginx, sem tocar PHP.
1️⃣ NGINX (proxy reverso) — peça mais importante
🔹 Função
- Cache de página
- Bloquear bots
- Servir estáticos
- Reduzir carga do Apache/PHP
🔹 Ajustes críticos
Cache FastCGI
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:256m inactive=60m max_size=20g; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale updating error timeout invalid_header http_500;
Ignorar cache só quando precisa
set $skip_cache 0;
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
if ($http_cookie ~* "wordpress_logged_in") { set $skip_cache 1; }
➡️ Visitante anônimo = HTML direto
2️⃣ Apache — reduzir ao mínimo
🔹 Regra
Apache não é cache, não é frontend.
🔹 Configuração ideal
- MPM:
event - KeepAlive baixo
- Workers enxutos
KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 2 StartServers 2 ServerLimit 32 MaxRequestWorkers 128
👉 Apache só “desempacota” PHP, nada mais.
3️⃣ PHP-FPM — evitar fila invisível
🔹 Pool recomendado (exemplo)
pm = dynamic pm.max_children = 40 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 15 request_terminate_timeout = 120s
📌 Regra prática
pm.max_children = RAM disponível para PHP / RAM média por processo
🔹 OPcache (obrigatório)
opcache.enable=1 opcache.memory_consumption=256 opcache.max_accelerated_files=100000 opcache.validate_timestamps=0
4️⃣ Redis — obrigatório em alto tráfego
🔹 Uso correto
- Transients
- Sessões
- Queries repetidas
🔹 Configuração base
maxmemory 1gb maxmemory-policy allkeys-lru
No WordPress:
- Plugin Redis Object Cache
- Prefixo único por site
5️⃣ MariaDB 11.3 — onde a maioria erra
🔹 Ajustes essenciais (my.cnf)
[mysqld] innodb_buffer_pool_size = 6G innodb_buffer_pool_instances = 6 innodb_log_file_size = 512M innodb_flush_log_at_trx_commit = 2 tmp_table_size = 256M max_heap_table_size = 256M max_connections = 300 thread_cache_size = 100
📌 Buffer pool ≈ 60–70% da RAM livre
6️⃣ WordPress — ajustes invisíveis que salvam
🔹 wp-config.php
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '256M');
define('DISABLE_WP_CRON', true);
define('WP_CACHE', true);
➡️ Use cron real no sistema:
*/5 * * * * php /site/wp-cron.php
Ajustar corretamente parâmetros como número de workers, pools do PHP-FPM e limites de memória ajuda a evitar gargalos antes que eles afetem usuários. Esse tipo de planejamento faz parte de uma gestão proativa de infraestrutura e performance de servidores.
7️⃣ Bots, crawlers e ataques leves
🔹 Rate limit no Nginx
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
location / {
limit_req zone=one burst=20 nodelay;
}
🔹 Bloquear lixo comum
xmlrpc.php(ou limite severo)wp-login.phpcom rate limit
8️⃣ Monitoramento mínimo (sem frescura)
O que observar SEMPRE
| Item | Comando |
|---|---|
| Fila PHP | pm.status_path |
| DB lento | slow_query_log |
| Cache hit | $upstream_cache_status |
| IO | iostat -x |
| Load real | htop |
🎯 Resultado esperado
| Situação | Antes | Depois |
|---|---|---|
| Pico de tráfego | PHP cai | Nginx absorve |
| Googlebot | Derruba | Cache |
| WooCommerce | Trava | Suportável |
| CPU | Oscila | Estável |
| DB | Gargalo | Última camada |
Abaixo está um nginx.conf completo, pronto para produção, pensado exatamente para:
- Nginx como proxy reverso
- Apache atrás
- PHP-FPM
- WordPress de alto tráfego
- Cache agressivo sem quebrar login/admin
- Seguro, estável e previsível
👉 É um arquivo base. Depois você só ajusta paths/domínios.
🧩 nginx.conf — WordPress alto tráfego (proxy + cache)
user nginx;
worker_processes auto;
worker_rlimit_nofile 200000;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
worker_connections 8192;
multi_accept on;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
# Performance geral
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15;
keepalive_requests 1000;
server_tokens off;
client_max_body_size 64m;
# Buffers
client_body_buffer_size 128k;
client_header_buffer_size 4k;
large_client_header_buffers 4 16k;
# Timeouts
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
send_timeout 60s;
# Logs (opcional reduzir)
access_log off;
# Gzip
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript
image/svg+xml;
# Cache FastCGI
fastcgi_cache_path /var/cache/nginx/wordpress
levels=1:2
keys_zone=WORDPRESS:256m
inactive=60m
max_size=20g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale updating error timeout invalid_header http_500 http_503;
fastcgi_cache_background_update on;
fastcgi_cache_lock on;
# Rate limit (bots / ataques leves)
limit_req_zone $binary_remote_addr zone=wp_limit:10m rate=5r/s;
# Apache backend
upstream apache_backend {
server 127.0.0.1:8080;
keepalive 32;
}
server {
listen 80 default_server reuseport;
server_name _;
root /var/www/html;
# Status cache (debug)
add_header X-Cache $upstream_cache_status always;
# Rate limit geral
limit_req zone=wp_limit burst=20 nodelay;
# Arquivos estáticos (não passam por Apache)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot|mp4|webm)$ {
expires 30d;
access_log off;
log_not_found off;
try_files $uri @apache;
}
# Bloqueios importantes
location = /xmlrpc.php {
deny all;
}
# Cache rules
set $skip_cache 0;
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
if ($request_uri ~* "/wp-admin/|/wp-login.php") {
set $skip_cache 1;
}
if ($http_cookie ~* "wordpress_logged_in|woocommerce_items_in_cart|wp_woocommerce_session") {
set $skip_cache 1;
}
location / {
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_cache WORDPRESS;
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
proxy_pass http://apache_backend;
}
location @apache {
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_pass http://apache_backend;
}
}
}
🔥 O que esse setup faz de verdade
✅ 90%+ das requisições morrem no Nginx
✅ Apache só processa o que realmente precisa de PHP
✅ PHP-FPM não cria fila invisível
✅ Bots não derrubam o site
✅ Cache respeita login, carrinho e admin
✅ Estáticos nunca passam por PHP
⚠️ Ajustes obrigatórios antes de usar
1️⃣ Confirme a porta do Apache
server 127.0.0.1:8080;
2️⃣ Confirme o path do cache
mkdir -p /var/cache/nginx/wordpress chown -R nginx:nginx /var/cache/nginx
3️⃣ Apache NÃO pode escutar na 80
📊 Resultado esperado em produção
| Situação | Resultado |
|---|---|
| Pico de tráfego | Estável |
| Googlebot | Cache |
| Home | < 50ms |
| PHP | Quase ocioso |
| DB | Última camada |
vamos evoluir esse setup para HTTPS + HTTP/2, sem quebrar cache, sem gambiarras e com ganho real de performance 👍
Abaixo está o mesmo nginx.conf, já adaptado, e depois explico por que cada coisa existe (pra você saber o que não mexer).
🔐 NGINX + HTTPS + HTTP/2 (WordPress alto tráfego)
Compatível com Let’s Encrypt, Apache atrás, cache agressivo e HTTP/2 ativo
🧩 Bloco completo (server HTTP + HTTPS)
🔁 Redirecionamento HTTP → HTTPS
server {
listen 80 reuseport;
server_name exemplo.com www.exemplo.com;
return 301 https://$host$request_uri;
}
🔒 Server HTTPS + HTTP/2
server {
listen 443 ssl http2 reuseport;
server_name exemplo.com www.exemplo.com;
root /var/www/html;
# Certificados
ssl_certificate /etc/letsencrypt/live/exemplo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemplo.com/privkey.pem;
# TLS moderno e rápido
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
# Headers de segurança (mínimos e seguros)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
# Debug de cache
add_header X-Cache $upstream_cache_status always;
# Rate limit
limit_req zone=wp_limit burst=20 nodelay;
# Estáticos
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot|mp4|webm)$ {
expires 30d;
access_log off;
log_not_found off;
try_files $uri @apache;
}
# Bloqueio XML-RPC
location = /xmlrpc.php {
deny all;
}
# Cache rules
set $skip_cache 0;
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
if ($request_uri ~* "/wp-admin/|/wp-login.php") {
set $skip_cache 1;
}
if ($http_cookie ~* "wordpress_logged_in|woocommerce_items_in_cart|wp_woocommerce_session") {
set $skip_cache 1;
}
location / {
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 https;
proxy_cache WORDPRESS;
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
proxy_pass http://apache_backend;
}
location @apache {
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_pass http://apache_backend;
}
}
⚙️ Ajustes obrigatórios no Apache (ATRÁS do HTTPS)
Apache deve “saber” que está em HTTPS
SetEnvIf X-Forwarded-Proto https HTTPS=on
📌 Sem isso:
- Cookies errados
- Login quebrado
- Redirect loop
⚙️ Ajustes obrigatórios no WordPress
wp-config.php
define('FORCE_SSL_ADMIN', true);
if (
isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'
) {
$_SERVER['HTTPS'] = 'on';
}
🚀 Por que HTTP/2 aqui realmente ajuda
Ajuda de verdade quando:
✔ Muitas imagens
✔ CSS/JS fragmentado
✔ Alta latência (mobile, 4G)
Não ajuda quando:
✖ Página já vem cacheada em HTML único
✖ Backend lento (HTTP/2 não salva PHP)
👉 HTTP/2 melhora entrega, não processamento.
🧠 Erros comuns (evite)
❌ Ativar HTTP/2 no Apache (inútil aqui)
❌ Cachear wp-admin
❌ Forçar cipher antigo
❌ Misturar SSL no Apache e no Nginx
📊 Testes pós-setup (obrigatório)
curl -I https://exemplo.com
Verifique:
HTTP/2 200X-Cache: HIT
revisar Apache + PHP-FPM pra fechar o ciclo
Perfeito — agora vamos fechar o ciclo e tirar todo o peso inútil do Apache e do PHP-FPM, deixando eles só para o que realmente não pode ser cacheado.
Isso é exatamente onde WordPress de alto tráfego costuma ganhar 30–60% de folga.
Vou assumir CloudLinux 8, Apache atrás do Nginx, PHP-FPM e tráfego alto.
🔧 Apache (atrás do Nginx) — mínimo, previsível e estável
🎯 Objetivo do Apache
- NÃO segurar conexões
- NÃO servir estáticos
- NÃO fazer SSL
- Apenas despachar PHP para o PHP-FPM
1️⃣ MPM correto (obrigatório)
Use MPM event
apachectl -M | grep mpm
Se não for event:
dnf install mod_mpm_event
Configuração recomendada
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 128
MaxConnectionsPerChild 5000
</IfModule>
📌 Regra de ouro: Apache nunca deve virar fila.
2️⃣ KeepAlive curto (ou vira armadilha)
KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 2
👉 O Nginx segura conexão longa, o Apache não.
3️⃣ Desligar o que não serve pra nada
Remova módulos inúteis
apachectl -M
Pode remover:
statusautoindexnegotiationdavuserdircgid
Menos módulos = menos memória = mais estabilidade.
4️⃣ Logs controlados (IO importa)
LogLevel warn CustomLog /var/log/httpd/access_log combined
Se possível, desligar access_log em produção pesada.
🧠 PHP-FPM — onde a fila invisível nasce
🎯 Objetivo
- Processos suficientes
- Sem swap
- Sem fila silenciosa
- Scripts lentos identificáveis
5️⃣ Pool PHP-FPM (exemplo sólido)
/etc/php-fpm.d/www.conf
pm = dynamic pm.max_children = 40 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 15 pm.max_requests = 500 request_terminate_timeout = 120s
📌 Como calcular pm.max_children
RAM disponível para PHP / RAM média por processo
👉 Normalmente 80–150 MB por processo em WP pesado.
6️⃣ Slowlog (obrigatório em produção)
request_slowlog_timeout = 3s slowlog = /var/log/php-fpm/slow.log
🔥 Isso mostra:
- Plugins ruins
- Queries lentas
- Funções pesadas
7️⃣ OPcache (não negociável)
/etc/php.d/10-opcache.ini
opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=100000 opcache.revalidate_freq=0 opcache.validate_timestamps=0 opcache.fast_shutdown=1
⚠️ Em update de plugin/tema:
systemctl reload php-fpm
8️⃣ PHP.ini — pequenos ajustes que evitam queda
memory_limit = 256M max_execution_time = 120 max_input_time = 60 post_max_size = 64M upload_max_filesize = 64M
🧪 Testes pós-ajuste (obrigatórios)
Apache
apachectl status
✔ Workers livres
✔ Nenhuma fila
PHP-FPM
curl http://127.0.0.1/status
✔ idle processes > 0
✔ listen queue = 0
Carga real
ab -n 1000 -c 50 https://exemplo.com/
✔ X-Cache: HIT
✔ PHP quase ocioso
🎯 Resultado final da stack
| Camada | Estado |
|---|---|
| Nginx | Cache + HTTP/2 |
| Apache | Despachante |
| PHP-FPM | Controlado |
| Redis | Cache quente |
| MariaDB | Última camada |
| WP | Estável |
👉 Agora o gargalo só aparece quando o tráfego é realmente absurdo — e aí já é escala horizontal, não tuning.
Infraestruturas preparadas para alto tráfego não dependem apenas de hardware mais potente, mas de planejamento e monitoramento contínuo. Equipes que adotam essa abordagem conseguem abandonar o modelo de operação reativa e evoluir para uma administração proativa de servidores.
FAQ
Sim. Quando combinado com PHP-FPM e cache, o Apache funciona muito bem em ambientes de alto tráfego.
Na prática sim. Ele permite controlar melhor os processos PHP e melhora muito o desempenho.
Depende da memória disponível e do consumo médio de cada processo PHP.
Sim. Redis reduz queries no banco e melhora o tempo de resposta.
Sim. Mesmo com PHP-FPM, o cache HTTP reduz drasticamente o processamento do servidor.
Veja Mais:
Operação reativa vs proativa: diferenças, riscos e boas práticas
Backup de Servidores Web: Guia de Estratégia e Otimização 2026
Como Otimizar Nextcloud para Grandes Equipes: Performance e Escalabilidade
Alertas que Antecipam Falhas em Servidores

