Guia prático para dimensionamento de VPS e tuning de PHP‑FPM para lojas Magento/OpenMage com picos sazonais: do sizing ao teste de carga
Por Kevin Marcondes · Publicado em · 8 min de leitura
Guia prático para dimensionamento de VPS e tuning de PHP‑FPM para lojas Magento/OpenMage com picos sazonais: transforme previsões de tráfego em capacidade, calcule workers e prepare cache e runtime. O objetivo é manter baixa latência mesmo com cache miss. Você sai com critérios objetivos, exemplos de configuração e validações para rodar antes da campanha.
O que muda em picos sazonais no Magento/OpenMage
Picos sazonais ampliam gargalos de CPU por núcleo, RAM e I/O, e expõem filas do PHP‑FPM. A meta é segurar latência baixa mesmo quando o cache falha.
Em Magento/OpenMage, o caminho quente costuma ser Nginx/Apache → PHP‑FPM → Redis (sessão/cache) → MySQL. Ao cair a taxa de acertos do cache, sobe a concorrência dinâmica e o consumo de memória por processo.
Planeje capacidade para o pior caso razoável (cache miss parcial), com sizing realista, parâmetros do FPM coerentes e caminhos de degradação controlados.
Como estimar o tráfego de pico sazonal?
A estimativa começa com RPS (requisições por segundo) e se converte em concorrência no PHP‑FPM. Foque nas rotas críticas e no mix de tráfego anônimo vs. logado.
Relacione taxa de acertos do cache, custo médio da requisição dinâmica e tempo de resposta alvo. Essas variáveis definem a concorrência necessária no pool do FPM.
- Colete RPS histórico por minuto em eventos anteriores.
- Estime hit ratio do cache por tipo de página (home, PLP, PDP, checkout).
- Meça o tempo médio de resposta dinâmico sob carga (p95).
- Concorrência alvo ≈ RPS_dinâmico × tempo_médio_resposta.
- Inclua picos relâmpago de campanhas (ex.: 2× em 10 min).
- Adicione margem para jobs Magento (consumers, indexers) na janela.
Quantos workers do PHP‑FPM eu preciso?
O número de workers depende da memória por processo e da concorrência desejada. Use uma fórmula simples, depois valide com teste de carga representativo.
Meça memória média por child em produção/staging (ps/top + pm.status) durante tráfego real. A partir daí, calcule pm.max_children e ajuste sob observabilidade.
- Memória disponível para PHP = RAM_total − SO − serviços (Redis/MySQL/nginx).
- Memória por child = pico observado sob carga + folga.
- pm.max_children ≈ floor(Mem_PHP / Mem_por_child).
- pm = dynamic para manter processos aquecidos no pico.
- pm.max_requests para reciclar alocações e conter vazamentos.
- Ajuste start/min/max_spare para evitar tempestade de forks.
; Exemplo inicial de pool (ajuste aos seus números)
[www]
pm = dynamic
pm.max_children = 120
pm.start_servers = 16
pm.min_spare_servers = 16
pm.max_spare_servers = 32
pm.max_requests = 1000
request_terminate_timeout = 60s
request_slowlog_timeout = 2s
slowlog = /var/log/php-fpm/www-slow.log
pm.status_path = /status
ping.path = /ping
ping.response = pong
Escolha de VPS: CPU, RAM, I/O e rede
O desempenho por núcleo pesa mais que a contagem de vCPUs. Prefira NVMe consistente, vCPU dedicada quando possível e monitore steal time da CPU.
I/O estável e latência de rede previsível evitam caudas longas. Ajuste a memória dedicada ao PHP de acordo com Redis, MySQL e web server presentes no host.
| Perfil de pico | vCPU | RAM para PHP | Disco/IOPS | Observações |
|---|---|---|---|---|
| Baixo (até 2k RPS cacheado) | 2–4 | 4–8 GB | NVMe básico | Foque em cache e opcache aquecido. |
| Médio (cache médio, miss relevante) | 4–8 | 8–16 GB | NVMe estável | Balanceie children com memória por processo. |
| Alto (promoções intensas) | 8–16 | 16–32 GB | NVMe priorizado | Separe web e fila, e considere escala horizontal. |
Cache de página, blocos e sessões para absorver rajadas
Cache reduz o trabalho do PHP no pico. Combine cache de página completa, cache de blocos e sessão externa para permitir escala horizontal sem sticky sessions.
Aumente a taxa de acertos com TTLs por rota, invalidação por evento e compressão. Trate o caminho de usuário anônimo como prioridade e proteja checkout com cache seletivo de blocos.
- Página completa com proxy de borda ou Varnish.
- Blocos dinâmicos via ESI/holes quando suportado.
- Sessões e page cache em Redis separados de filas.
- Headers corretos para variar por device/região.
- Compressão gzip/brotli quando aplicável.
- Monitore hit ratio por rota e por tipo de usuário.
Como preparar o PHP‑FPM para rajadas em datas especiais?
Preparar o runtime reduz caudas de latência. Faça warm‑up do opcache, ajuste limites de arquivos e habilite slowlog para caçar N+1 e consultas lentas.
Revise backlog do web server, conexões com Redis/MySQL e timeouts do gateway. Pequenos ajustes evitam cascatas quando há cache miss parcial.
- Warming de opcache após deploy para não compilar sob pico.
- realpath_cache_size e TTLs coerentes com Magento/OpenMage.
- rlimit_files/ulimit para evitar “Too many open files”.
- request_terminate_timeout para travas ocasionais.
- emergency_restart_threshold/interval para stucks raros.
- Backlog do listener alinhado ao front (net.core.somaxconn).
- Healthchecks e status paths expostos e protegidos.
; opcache (ajuste conforme seu código e catálogos)
[opcache]
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=65407
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.save_comments=1
opcache.jit=0
Escalar horizontalmente com segurança e sem sticky sessions
Escala horizontal exige instâncias web stateless. Guarde sessões e cache fora do nó e trate assets compartilhados para poder subir e descer nós no pico.
Implemente health checks e readiness para retirar nós do balanceador sem derrubar sessões. Planeje deploys sem impacto na janela crítica.
- Sessões em Redis e sem sticky sessions no balanceador.
- Media em storage de objetos ou NFS robusto.
- Consumers/indexers em nós separados com limites claros.
- Readiness e liveness no web para evitar tráfego a nó frio.
- Blue/green ou canário fora de janelas críticas.
Como validar o sizing antes da Black Friday?
Valide a capacidade com testes de carga que simulam mix real e falha parcial de cache. Replique picos relâmpago e anomalias de tráfego para reduzir surpresas.
Meça p95/p99 por rota, saturação de CPU, filas do PHP‑FPM e steal time. Ajuste parâmetros, repita e congele configurações após atingir as metas.
- Cenários: anônimo com cache, logado sem cache e checkout.
- Scripts k6 com estágios e picos de curta duração.
- Monitoração: pm.status, slowlog e tempos de query no DB.
- Critérios de sucesso com error budget e latência alvo.
- Teste de rollback de deploy e de feature flags.
- Concorrência estimada validada em teste de carga.
- pm.max_children calculado pelo uso real de memória.
- pm.status, ping e slowlog habilitados e protegidos.
- Opcache aquecido e parâmetros ajustados ao código.
- Redis separado para sessão e page cache.
- Backlog do web e do FPM coerentes com tráfego.
- Limites de arquivos ajustados no SO e no FPM.
- Playbook de escala horizontal testado.
- Alertas de p95/p99 e fila do FPM configurados.
- Plano de rollback de deploy pronto.
Perguntas frequentes
Qual é a fórmula prática para definir pm.max_children?
A fórmula é: pm.max_children ≈ floor(Memória_disponível_para_PHP ÷ Memória_por_child). Meça memória por child sob carga com ps/pm.status. Inclua folga para picos curtos e outros serviços no host, e valide com testes de carga.
Devo usar pm=dynamic ou pm=ondemand para Magento/OpenMage?
Para picos previsíveis, pm=dynamic mantém processos aquecidos e reduz cauda de latência. pm=ondemand economiza RAM no off‑peak, mas pode aumentar latência ao criar processos. Em campanhas, prefira dynamic ou pré‑aquecer ondemand.
PHP 8 JIT ajuda em Magento/OpenMage?
Em geral, JIT traz pouco ganho para aplicações web I/O‑bound como Magento/OpenMage. Priorize opcache, queries e tuning do FPM. Teste em staging com sua carga antes de habilitar JIT em produção.
Preciso de Varnish para aguentar picos?
Não é obrigatório, mas um proxy de cache de página eleva muito a capacidade. Combine com invalidação correta e sessão em Redis para liberar o PHP‑FPM. Sem cache, o sizing de CPU/RAM deve ser maior para suportar miss.
Uso o mesmo Redis para sessão e cache de página?
O ideal é separar instâncias ou ao menos bancos e políticas de eviction. Sessões não devem competir com chaves de página. Defina TTLs, tamanhos e eviction coerentes com cada finalidade.
Quando escalar verticalmente e quando escalar horizontalmente?
Escale verticalmente enquanto houver ganhos claros com mais CPU/RAM e menor custo. Escale horizontalmente ao bater limites de núcleo único, I/O ou quando precisa isolar riscos e manter deploys sem downtime.
Quer revisar sizing e tuning antes da próxima campanha?
Se você precisa validar capacidade, ajustar PHP‑FPM e preparar escala segura para Magento/OpenMage, vamos conversar sobre um plano objetivo e testável.
Solicitar uma conversa técnicaVeja também
- Guia prático: como configurar failover ativo-passivo entre duas VPS com Keepalived, HAProxy e lsyncd para uploads sincronizados
- Guia: checklist técnico para preparar VPS Debian com Docker Compose para aplicações PHP em produção
- guia prático: reconstruir índices no PostgreSQL em produção usando CREATE INDEX CONCURRENTLY e índices parciais (passo a passo seguro)
- Guia prático para implementar retries exponenciais e circuit breaker em integrações entre ERP e marketplaces