MV Melhor VPS

Guia

Como otimizar Nginx para alta performance

Guia prático para otimizar Nginx em VPS: workers, cache, gzip, HTTP/2, buffers, logs, testes e rollback seguro para produção.

Revisão editorial: Concluída
⏱ Tempo estimado: 40-50 minutos
📊 Dificuldade: Avançado

O que você vai aprender

Este guia mostra como otimizar Nginx em uma VPS sem cair na armadilha de copiar blocos de configuração aleatórios. Você vai medir o estado atual, ajustar workers, conexões, compressão, cache estático, buffers, timeouts, HTTP/2, TLS e logs. A ideia não é transformar um VPS pequeno em um cluster de alta disponibilidade, mas remover gargalos comuns e deixar o servidor previsível.

Você vai aprender a:

  • medir latência e throughput antes de mudar configuração;
  • ajustar worker_processes, worker_connections e multi_accept;
  • ativar cache estático com headers coerentes;
  • configurar gzip para respostas textuais;
  • revisar buffers e timeouts para APIs, WordPress e aplicações Node;
  • validar sintaxe com nginx -t e recarregar sem derrubar o serviço;
  • identificar problemas comuns em logs.

Se você ainda está escolhendo infraestrutura, leia também o guia sobre CPU, RAM e NVMe. Nginx bem configurado ajuda, mas ele não compensa disco lento, pouca RAM ou aplicação mal dimensionada.

Pré-requisitos

Você precisa de acesso SSH a uma VPS Linux com Nginx instalado, permissões sudo e um domínio apontando para o servidor se quiser validar HTTPS. Os comandos abaixo usam caminhos comuns em Ubuntu e Debian. Em distribuições diferentes, confira o caminho principal de configuração antes de editar.

Antes de alterar qualquer coisa, faça backup:

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%F-%H%M)
sudo cp -r /etc/nginx/sites-available /etc/nginx/sites-available.bak.$(date +%F-%H%M)

Verifique a versão:

nginx -v

Saída esperada:

nginx version: nginx/1.24.0

Também confirme se o serviço está ativo:

systemctl status nginx --no-pager

Se o Nginx já atende tráfego real, aplique uma mudança por vez e use reload, não restart, sempre que possível.

Passo 1: Medir antes de alterar

O erro mais comum é “otimizar” sem saber o gargalo. Primeiro capture uma linha de base. Teste o tempo de resposta local:

curl -o /dev/null -s -w 'dns:%{time_namelookup} connect:%{time_connect} start:%{time_starttransfer} total:%{time_total}\n' https://seudominio.com.br/

Você deve receber algo parecido com:

dns:0.004 connect:0.022 start:0.091 total:0.104

Depois veja erros e status recentes:

sudo tail -n 100 /var/log/nginx/access.log
sudo tail -n 100 /var/log/nginx/error.log

Se houver muitos 499, clientes estão encerrando conexão antes da resposta. Se houver 502 ou 504, o gargalo pode estar no upstream, como PHP-FPM, Node, Python ou uma API interna. Para WordPress, combine esta análise com o guia de VPS para WordPress. Para APIs, veja também VPS para API.

Para um teste simples de carga, instale ApacheBench:

sudo apt update
sudo apt install apache2-utils -y

Rode um teste moderado:

ab -n 500 -c 20 https://seudominio.com.br/

Não use concorrência alta em produção sem janela de manutenção. O objetivo é comparar antes/depois, não derrubar o próprio servidor.

Passo 2: Ajustar workers e conexões

Abra o arquivo principal:

sudo nano /etc/nginx/nginx.conf

Um ponto de partida seguro para VPS é:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

worker_processes auto usa a quantidade de CPUs disponíveis. worker_connections define quantas conexões cada worker pode manter. Em um VPS pequeno, 1024 costuma ser suficiente. Em workloads com muitos arquivos estáticos ou conexões keep-alive, você pode testar 2048, mas monitore memória.

Verifique o limite de arquivos:

ulimit -n

Se o valor for muito baixo para tráfego alto, ajuste o serviço via systemd. Crie um override:

sudo systemctl edit nginx

Adicione:

[Service]
LimitNOFILE=65535

Recarregue o systemd e o Nginx:

sudo systemctl daemon-reload
sudo nginx -t
sudo systemctl reload nginx

Saída esperada do teste:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Passo 3: Ativar compressão e cache estático

Gzip reduz o tamanho de HTML, CSS, JavaScript e JSON. Em /etc/nginx/nginx.conf, dentro do bloco http, use:

gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_vary on;
gzip_proxied any;
gzip_types
    text/plain
    text/css
    text/xml
    application/json
    application/javascript
    application/xml
    image/svg+xml;

Não comprima imagens já otimizadas. Para assets estáticos, adicione no server block:

location ~* \.(?:css|js|svg|png|jpg|jpeg|webp|avif|ico|woff2?)$ {
    expires 30d;
    add_header Cache-Control "public, max-age=2592000, immutable";
    try_files $uri =404;
}

Esse bloco funciona bem para sites Astro, WordPress com cache de página e aplicações com build versionado. Se o seu app troca arquivos mantendo o mesmo nome, remova immutable ou reduza o prazo.

Teste headers:

curl -I https://seudominio.com.br/assets/app.css

Procure por:

cache-control: public, max-age=2592000, immutable
content-encoding: gzip

Se o arquivo não aparece comprimido, talvez ele seja pequeno, esteja atrás de CDN ou o tipo MIME não esteja na lista.

Passo 4: Revisar buffers, timeouts e uploads

Buffers e timeouts errados causam sintomas chatos: upload quebrando, API com 504, WordPress lento no admin ou conexões presas. Um bloco http equilibrado para VPS pode usar:

client_body_buffer_size 128k;
client_max_body_size 32m;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;

Para uploads maiores, ajuste client_max_body_size conforme o caso. Em WordPress, 32m ou 64m costuma ser suficiente para sites comuns; lojas e áreas administrativas podem precisar mais. Em APIs, evite aceitar payload gigante sem necessidade.

Se você usa proxy para Node, Docker ou upstream HTTP, configure timeouts de forma explícita:

location / {
    proxy_pass http://127.0.0.1:3000;
    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 X-Forwarded-Proto $scheme;
    proxy_connect_timeout 10s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
}

Para APIs com jobs longos, pense melhor na arquitetura: filas e workers geralmente são mais confiáveis que aumentar timeout indefinidamente.

Passo 5: Validar HTTP/2, TLS e logs

Em servidores HTTPS, habilite HTTP/2 no listen quando sua versão do Nginx suportar:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name seudominio.com.br;
}

TLS moderno depende do certificado e da configuração do sistema. Se usa Let’s Encrypt, valide:

sudo certbot certificates
sudo nginx -t

Para logs, um formato com tempo de resposta ajuda a achar gargalos:

log_format timed '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 'rt=$request_time uct=$upstream_connect_time '
                 'uht=$upstream_header_time urt=$upstream_response_time';

access_log /var/log/nginx/access.log timed;

Depois recarregue:

sudo nginx -t
sudo systemctl reload nginx

Monitore:

sudo tail -f /var/log/nginx/access.log

Se request_time está baixo e upstream_response_time está alto, o gargalo está na aplicação. Se ambos estão altos, investigue rede, disco, CPU, TLS ou excesso de conexões.

Verificação e testes

Faça uma bateria curta:

sudo nginx -t
systemctl is-active nginx
curl -I https://seudominio.com.br/
ab -n 500 -c 20 https://seudominio.com.br/

Resultados esperados:

active
HTTP/2 200
Complete requests: 500
Failed requests: 0

Compare com a linha de base do início. Se a latência não melhorou, não force novos ajustes no Nginx. Olhe CPU, RAM, I/O, banco de dados e aplicação. Em VPS com disco lento, migrar para VPS com NVMe pode ter mais impacto que qualquer ajuste de configuração.

Troubleshooting

Nginx não recarrega após a mudança

Rode:

sudo nginx -t

Leia a linha do erro. O Nginx normalmente informa arquivo e linha. Corrija antes de tentar reload. Para voltar rápido:

sudo cp /etc/nginx/nginx.conf.bak.YYYY-MM-DD-HHMM /etc/nginx/nginx.conf
sudo nginx -t
sudo systemctl reload nginx

Site fica com 502 Bad Gateway

O Nginx está ativo, mas o upstream não respondeu. Verifique o serviço por trás:

systemctl status php8.3-fpm --no-pager
systemctl status sua-aplicacao --no-pager

Também confira se proxy_pass ou fastcgi_pass aponta para porta/socket correto.

Uploads falham

Revise client_max_body_size no bloco correto. Se há CDN ou proxy antes do Nginx, ela também pode ter limite próprio.

Performance piorou após gzip

Em VPS com pouca CPU, compressão alta pode custar mais do que economiza. Reduza gzip_comp_level para 4 ou 5, ou deixe compressão pesada para a CDN.

Próximos passos

Depois de estabilizar o Nginx, avance para monitoramento, backup e dimensionamento. Configure alertas de CPU, RAM, disco e HTTP 5xx. Teste restore de backup, não apenas a criação do arquivo. Para workloads que crescem, avalie separar banco de dados, cache e aplicação em camadas diferentes.

Se o projeto atende público brasileiro, combine a otimização com uma escolha adequada de região. O guia de VPS no Brasil ou exterior ajuda a decidir quando latência local importa.

Perguntas frequentes

Qual é o primeiro ajuste de performance que devo fazer no Nginx?

O primeiro ajuste deve ser medir o estado atual. Sem métricas de latência, CPU, conexões e códigos de resposta, qualquer otimização vira tentativa. Comece com access logs, ferramentas como curl, ab ou wrk, e compare antes e depois de cada alteração.

worker_processes auto é sempre a melhor opção?

Na maioria dos VPS modernos, worker_processes auto é um bom ponto de partida porque o Nginx ajusta workers conforme os núcleos disponíveis. Ainda assim, você deve observar CPU, memória e conexões reais, principalmente em VPS pequenos ou workloads com upstreams lentos.

Gzip melhora qualquer site?

Gzip melhora HTML, CSS, JavaScript, JSON e SVG, mas não ajuda arquivos já comprimidos, como imagens JPEG, PNG, WebP, ZIP ou vídeos. Ative compressão com tipos corretos e teste o consumo de CPU em VPS muito pequenos.

Cache estático no Nginx substitui CDN?

Não. Cache estático no Nginx reduz carga no servidor de origem e melhora respostas locais, mas uma CDN ainda ajuda quando o público está distribuído geograficamente. Para público brasileiro, combine origem bem configurada com CDN quando houver tráfego relevante.

Como evitar quebrar produção ao otimizar Nginx?

Faça backup dos arquivos de configuração, aplique mudanças pequenas, rode nginx -t antes de reload e monitore logs após cada ajuste. Prefira systemctl reload nginx em vez de restart para evitar interromper conexões ativas sem necessidade.

Fontes consultadas