A configuração de timeouts e conexões persistentes (keepalive) é um dos ajustes mais impactantes para o desempenho de servidores web rodando em ambientes de Virtual Private Server (VPS). Muitos administradores focam exclusivamente na otimização do PHP ou do banco de dados, negligenciando a camada de transporte que conecta o cliente ao servidor. Em cenários de alta concorrência ou com usuários em conexões lentas, uma configuração inadequada pode resultar em timeouts prematuros, consumo excessivo de memória RAM devido a conexões zumbis e degradação significativa da experiência do usuário.
Neste tutorial, vamos detalhar como ajustar corretamente os parâmetros timeout e keepalive tanto no Apache quanto no Nginx em uma VPS Ubuntu. O objetivo é equilibrar a retenção de conexões ativas para aproveitar o reuso de TCP (evitando o overhead do handshake TLS e TCP) com a liberação rápida de recursos para novos solicitantes.
1. Conceitos Fundamentais: Timeout vs. Keepalive
Antes de aplicar as configurações, é crucial entender a diferença entre os dois conceitos, pois eles atuam em camadas diferentes do ciclo de vida da conexão HTTP.
O Keepalive permite que múltiplos requisições e respostas sejam transmitidas sobre uma única conexão TCP. Sem ele, o navegador precisaria estabelecer uma nova conexão TCP (e realizar o handshake TLS) para cada arquivo estático (CSS, JS, imagens). Isso reduz drasticamente a latência percebida pelo usuário.
O Timeout, por outro lado, define quanto tempo o servidor aguarda por uma nova requisição dentro de uma conexão keepalive aberta antes de fechá-la. Se um cliente abrir uma conexão e não enviar nada por 60 segundos, o servidor libera esse recurso. Definir esse valor muito alto pode levar ao acúmulo de milhares de conexões ociosas, esgotando a tabela de sockets do sistema operacional.
A otimização consiste em encontrar o ponto ideal: manter a conexão aberta tempo suficiente para aproveitar o cache local do navegador e reduzir latência, mas não tanto a ponto de consumir recursos desnecessários do servidor.
2. Otimizando o Apache no Ubuntu
O Apache lida com conexões através de MPMs (Multi-Processing Modules). A configuração varia dependendo se você está usando prefork, worker ou event. Em versões modernas do Ubuntu, o mpm-event é frequentemente o padrão para PHP-FPM devido à sua eficiência em concorrência.
O arquivo de configuração principal geralmente fica em /etc/apache2/mods-enabled/mpm_event.conf (ou similar, dependendo do módulo ativo). No entanto, os parâmetros de timeout e keepalive são definidos no contexto global ou no arquivo de configurações de conexão.
2.1. Ativando e Configurando o Módulo MPM
Verifique qual módulo está ativo:
a2query -m mpm_event
Se estiver usando PHP com Apache, é comum usar o módulo mod_mpm_event. Edite o arquivo de configuração do MPM:
sudo nano /etc/apache2/mods-available/mpm_event.conf
Dentro deste arquivo, ajuste os limites de processos. Embora não sejam timeouts diretos, eles impactam a capacidade de aceitar novas conexões keepalive:
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
2.2. Configurando Timeouts e Keepalive no Apache
A configuração específica de timeout e keepalive reside no arquivo conf-enabled/timeout.conf ou diretamente no apache2.conf. Vamos editar o arquivo de configurações adicionais:
sudo nano /etc/apache2/conf-available/timeouts.conf
Crie ou edite o conteúdo com as seguintes diretrizes. Estas são configurações equilibradas para uma VPS média:
<IfModule mod_mime.c>
# Tempo máximo que o servidor aguarda por um bloco de envio
# Padrão: 300s. Recomendado: 60-120s para evitar bloqueios longos
Timeout 120
# Tempo máximo para receber uma requisição HTTP completa do cliente
# Se um script demorar mais que isso, ele será interrompido
# Importante: Deve ser maior que o max_execution_time do PHP
RequestReadTimeout header=40-120,MinRate=500 body=20,Libcurl-timeout=30
# Habilita conexões persistentes
KeepAlive On
# Número máximo de requisições permitidas por conexão keepalive
# 0 significa ilimitado (não recomendado para segurança e estabilidade)
KeepAliveTimeout 5
# Número máximo de conexões keepalive aguardando no buffer do servidor
# Aumenta a capacidade de lidar com picos súbitos de tráfego
MaxKeepAliveRequests 100
</IfModule>
Explicação dos parâmetros:
Timeout 120: Define o limite global. Para APIs ou uploads grandes, você pode aumentar, mas para sites institucionais, 60-90s é suficiente.KeepAliveTimeout 5: Este é o valor mais crítico. Um valor de 4 a 5 segundos é o padrão ouro. Se seu site carrega muito rápido e os usuários navegam depressa, você pode testar com 2s. Se seus usuários estão em redes móveis lentas (3G/4G), mantenha 5s ou aumente para 10s.MaxKeepAliveRequests 100: Limita o uso de uma única conexão TCP. Isso evita que um único cliente monopolize a thread do servidor indefinidamente.
Após salvar, verifique a sintaxe e reinicie:
sudo apache2ctl configtest
sudo systemctl restart apache2
3. Otimizando o Nginx no Ubuntu
O Nginx é conhecido por sua arquitetura assíncrona e eficiente no manejo de conexões keepalive. A configuração principal fica em /etc/nginx/nginx.conf. Diferente do Apache, que pode precisar de múltiplos arquivos, o Nginx centraliza essas definições.
3.1. Acessando a Configuração Principal
sudo nano /etc/nginx/nginx.conf
Você deve localizar o bloco http. É dentro deste bloco que as diretrizes globais são aplicadas.
3.2. Diretivas de Timeout e Keepalive no Nginx
Adicione ou modifique as seguintes linhas dentro do bloco http { ... }:
http {
# Habilita conexões persistentes
keepalive_timeout 65;
# Tamanho máximo do cabeçalho da requisição (em bytes)
# Ajuste conforme necessário, padrão é 4k/8k
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# Tempo limite para leitura do corpo da requisição (upload)
# Padrão: 60s. Aumente se você aceita uploads de vídeo/fotos grandes
client_body_timeout 60;
# Tempo limite para envio de resposta ao cliente
send_timeout 60;
# ... outras configurações ...
}
Análise detalhada das diretivas:
keepalive_timeout 65: No Nginx, este valor define quanto tempo uma conexão keepalive permanece aberta após o envio da resposta. O padrão é 75 segundos em algumas versões, mas 65s é um valor seguro que evita timeouts de TCP no meio do caminho (NAT firewalls costumam fechar conexões após ~60-120s). Se você estiver atrás de um balanceador de carga ou CDN, ajuste conforme a configuração deles.client_header_buffer_size: Define o buffer para cabeçalhos pequenos. Aumentar isso pode ajudar em requisições com cookies grandes, mas consome mais memória por conexão.client_body_timeout 60: Se um cliente iniciar o envio de um POST (upload) e parar por mais de 60 segundos, o Nginx fecha a conexão. Isso protege contra ataques de lentidão (slowloris) e libera recursos rapidamente.send_timeout 60: Tempo limite para transferência de dados de resposta. Se um usuário pausar o download, o servidor esperará 60 segundos antes de fechar. Para sites estáticos leves, você pode reduzir para 30s.
3.3. Otimização Avançada: Keepalive no Proxy (Backend)
Se você usa Nginx como reverse proxy para uma aplicação Node.js, Python ou PHP-FPM, é vital configurar o keepalive na comunicação entre o Nginx e o backend.
upstream php-fpm {
server 127.0.0.1:9000;
# Mantém conexões abertas com o backend para evitar overhead de conexão constante
keepalive 32;
}
server {
location ~ \.php$ {
proxy_pass http://php-fpm;
# Passa os headers corretos para manter a conexão
proxy_http_version 1.1;
proxy_set_header Connection "";
# Timeout da comunicação com o backend
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
A diretiva keepalive 32 no bloco upstream define quantas conexões inativas com o backend serão mantidas em cache. Isso evita que o Nginx abra e feche conexões TCP para cada requisição PHP, melhorando drasticamente a latência.
4. Ajustes no Sistema Operacional (Ubuntu)
Configurações de aplicação só funcionam bem se o kernel do Linux estiver preparado para lidar com muitas conexões simultâneas. Em VPSs com pouca memória RAM, os limites padrão podem ser baixos.
4.1. Ajustando o Limite de Arquivos e Sockets
Verifique o limite atual de arquivos abertos:
ulimit -n
Se for inferior a 65535, edite o arquivo /etc/security/limits.conf:
sudo nano /etc/security/limits.conf
Adicione as seguintes linhas para garantir que os serviços possam abrir muitas conexões:
* soft nofile 65535
* hard nofile 65535
www-data soft nofile 65535
www-data hard nofile 65535
4.2. Otimização do TCP Stack (sysctl)
Edite o arquivo de configurações do kernel:
sudo nano /etc/sysctl.conf
Adicione ou verifique estas linhas para otimizar o gerenciamento de memória e sockets TCP:
# Aumenta o tamanho máximo da fila de conexões pendentes
net.core.somaxconn = 4096
# Habilita reuso rápido de sockets em estado TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
# Reduz o tempo que uma conexão fica em estado TIME_WAIT
# Padrão é 60s, reduzir para 30s libera memória mais rápido
net.ipv4.tcp_fin_timeout = 30
# Aumenta o espaço de buffer TCP
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
Para aplicar as mudanças imediatamente sem reiniciar:
sudo sysctl -p
5. Validação e Monitoramento Pós-Configuração
Após aplicar todas as alterações, é essencial validar se o servidor está respondendo conforme esperado.
5.1. Teste de Sintaxe
Sempre teste a configuração antes de reiniciar:
# Para Apache
sudo apache2ctl configtest
# Para Nginx
sudo nginx -t
Se o retorno for successful, reinicie os serviços:
sudo systemctl restart apache2
# ou
sudo systemctl restart nginx
5.2. Monitoramento de Conexões
Use ferramentas de linha de comando para visualizar o impacto. Para ver quantas conexões estão no estado ESTABLISHED (ativas) e TIME_WAIT:
sudo ss -s
O comando ss (socket statistics) é mais rápido e informativo que o antigo netstat. Observe a linha "TCP: eth0" no final. Se você vir um número excessivo de conexões em TIME_WAIT, considere reduzir o tcp_fin_timeout no sysctl ou ajustar o keepalive timeout para um valor menor.
Além disso, monitore o uso de memória RAM e CPU. Um erro comum é definir timeouts altos demais, fazendo com que o servidor retenha milhares de conexões ociosas, consumindo memória RAM desnecessária. Use htop ou top para verificar se o consumo de memória subiu desproporcionalmente após a mudança.
6. Boas Práticas e Considerações Finais
A otimização de timeouts não é um "tamanho único". O valor ideal depende do seu perfil de tráfego:
- Sites Institucionais/Blogs: Tráfego baixo, usuários navegam lentamente. Keepalive timeout alto (10-30s) ajuda a carregar múltiplos recursos estáticos rapidamente.
- APIs e Aplicativos Móveis: Muitas requisições pequenas e rápidas. Keepalive é essencial, mas o timeout pode ser menor (5-10s), pois as conexões são estabelecidas frequentemente por bibliotecas HTTP modernas que já otimizam o pooling.
- E-commerce em Promoções: Priorize a liberação rápida de recursos. Mantenha timeouts moderados e foque em aumentar os limites de processos (MaxRequestWorkers ou worker_processes) para lidar com a concorrência.
Lembre-se também que, se você utiliza uma CDN (como Cloudflare ou AWS CloudFront), as configurações de timeout do seu servidor de origem devem ser compatíveis com a CDN. Se a CDN mantém a conexão keepalive aberta por 300 segundos e seu servidor fecha em 5 segundos, a conexão será fechada prematuramente durante o intervalo entre requisições da CDN para o backend, anulando os benefícios.
Ajustar timeouts e keepalive é um exercício de equilíbrio. Comece com os valores recomendados neste guia, monitore o desempenho por alguns dias e ajuste finamente conforme a resposta real dos seus usuários. A estabilidade do servidor depende tanto de saber quando fechar uma conexão quanto de saber quando mantê-la viva.