Linux: tuning de kernel com sysctl para alto tráfego

O kernel Linux vem configurado para uso geral, não para servidores web de alto tráfego. Com ajustes no sysctl e nos limites do sistema, você elimina gargalos invisíveis: conexões recusadas em picos de tráfego, file descriptors esgotados, buffers TCP subdimensionados e TIME_WAIT acumulado.

Configurações essenciais de rede no sysctl

Parâmetros críticos para servidores web e APIs:

bash
# /etc/sysctl.d/99-vps-performance.conf

# ── Conexões TCP ───────────────────────────────────────────
# Backlog de conexões aguardando accept():
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535

# Reutilizar sockets em TIME_WAIT (evita esgotamento de portas):
net.ipv4.tcp_tw_reuse = 1

# Manter conexões keep-alive por menos tempo:
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5

# Timeout de FIN (reduzir TIME_WAIT):
net.ipv4.tcp_fin_timeout = 15

# ── Buffers de rede ────────────────────────────────────────
net.core.rmem_max = 134217728          # 128 MB — buffer receive máximo
net.core.wmem_max = 134217728          # 128 MB — buffer send máximo
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864

# Fila de pacotes de rede:
net.core.netdev_max_backlog = 250000

# ── Limites gerais ─────────────────────────────────────────
# File descriptors globais:
fs.file-max = 2097152

# Aplicar imediatamente:
sudo sysctl -p /etc/sysctl.d/99-vps-performance.conf

# Verificar valor atual de qualquer parâmetro:
sysctl net.core.somaxconn

Aumentar limites de file descriptors

Nginx e Node.js precisam de muitos file descriptors para conexões simultâneas:

bash
# /etc/security/limits.conf — adicionar ao final:
*         soft    nofile    1048576
*         hard    nofile    1048576
root      soft    nofile    1048576
root      hard    nofile    1048576

# Para serviços systemd — override:
sudo mkdir -p /etc/systemd/system/nginx.service.d/
cat > /etc/systemd/system/nginx.service.d/limits.conf << 'EOF'
[Service]
LimitNOFILE=1048576
EOF

sudo mkdir -p /etc/systemd/system/node-app.service.d/
cat > /etc/systemd/system/node-app.service.d/limits.conf << 'EOF'
[Service]
LimitNOFILE=1048576
EOF

# Recarregar e verificar:
sudo systemctl daemon-reload
sudo systemctl restart nginx

# Ver limite atual do processo Nginx:
NGINX_PID=$(pgrep nginx | head -1)
cat /proc/$NGINX_PID/limits | grep "open files"

# Verificar uso de file descriptors em tempo real:
watch -n 1 "ls /proc/$NGINX_PID/fd | wc -l"

Tuning do Nginx para alto tráfego

Configurações do Nginx que dependem do sysctl:

nginx
# /etc/nginx/nginx.conf

worker_processes auto;           # um worker por CPU
worker_rlimit_nofile 1048576;    # limite de files por worker

events {
    worker_connections 65535;    # máximo de conexões por worker
    use epoll;                   # melhor performance no Linux
    multi_accept on;             # aceitar múltiplas conexões por ciclo
}

http {
    # Keepalive entre Nginx e upstream (Node.js):
    upstream nodejs {
        server 127.0.0.1:3000;
        keepalive 64;            # pool de 64 conexões persistentes
    }

    server {
        location / {
            proxy_pass http://nodejs;
            proxy_http_version 1.1;
            proxy_set_header Connection "";  # necessário para keepalive
        }
    }

    # Buffer de leitura do cliente:
    client_body_buffer_size 128k;
    client_max_body_size 10m;
    client_header_buffer_size 1k;

    # Enviar arquivos eficientemente (zero-copy):
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # Keepalive com clientes:
    keepalive_timeout 65;
    keepalive_requests 10000;
}

Monitorar e diagnosticar gargalos de rede

Ferramentas para identificar onde o sistema está travando:

bash
# Conexões TCP por estado:
ss -s

# Ver sockets em TIME_WAIT (se acima de 10k: problema):
ss -tan state time-wait | wc -l

# Ver sockets em ESTABLISHED:
ss -tan state established | wc -l

# Estatísticas de erros TCP:
netstat -s | grep -E "failed|overflow|reject|retransmit"

# Overflow na fila de SYN:
netstat -s | grep "SYN to LISTEN"
# Se crescendo: aumentar net.ipv4.tcp_max_syn_backlog

# File descriptors em uso por processo:
ls /proc/$(pgrep node | head -1)/fd | wc -l
ls /proc/$(pgrep nginx | head -1)/fd | wc -l

# Monitorar throughput de rede em tempo real:
iftop -i eth0
# ou:
nethogs eth0

# Ver interrupções de CPU por NIC (IRQ affinity):
cat /proc/interrupts | grep eth

BBR: algoritmo de congestionamento TCP moderno

Habilitar BBR para melhor throughput em conexões de longa distância:

bash
# BBR (Bottleneck Bandwidth and Round-trip propagation time)
# Desenvolvido pelo Google — melhora throughput em redes com perda de pacotes

# Verificar se o kernel suporta (Linux 4.9+):
uname -r  # deve ser 4.9+

# Habilitar BBR:
echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.d/99-bbr.conf
echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.d/99-bbr.conf
sudo sysctl -p /etc/sysctl.d/99-bbr.conf

# Verificar se está ativo:
sysctl net.ipv4.tcp_congestion_control
# Deve retornar: net.ipv4.tcp_congestion_control = bbr

# Comparar algoritmos disponíveis:
sysctl net.ipv4.tcp_available_congestion_control

# BBR é especialmente benéfico para:
# - VPS em diferentes regiões geográficas
# - Usuários com conexões lentas ou instáveis
# - APIs com payloads grandes (uploads/downloads)
# - Streaming de dados via SSE ou WebSocket

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

sysctl configura parâmetros do kernel, afeta todos os processos e serviços rodando no sistema. Os valores do /etc/sysctl.d/ são aplicados no boot e persistem. Para valores temporários (teste sem afetar produção): use sysctl -w net.core.somaxconn=1024 sem salvar no arquivo. Para rollback: reiniciar o servidor restaura os valores dos arquivos de configuração.

TIME_WAIT é o estado TCP após fechar uma conexão, o kernel mantém a conexão por 2×MSL (padrão: 60s no Linux) para garantir que pacotes atrasados não sejam aceitos em novas conexões. Problema: cada porta ephemeral usada em TIME_WAIT não pode ser reutilizada. Com muitas requisições por segundo, o pool de portas (60000+) pode esgotar. tcp_tw_reuse = 1 permite reutilizar essas portas quando seguro.

Limite teórico: worker_processes × worker_connections no Nginx. Limite prático: limitado por file descriptors (ulimit -n), memória RAM e sysctl somaxconn. Uma VPS com 2 GB RAM pode sustentar ~10.000-20.000 conexões simultâneas. Use k6 para teste de carga real e monitore com ss -s durante o teste.

CUBIC (padrão): assume que perda de pacote = congestionamento e reduz drasticamente a velocidade. BBR: modela a largura de banda real da rede, mais robusto com perda de pacote. Para VPS no Brasil servindo usuários com conexões instáveis ou usuários em outras regiões: BBR tipicamente melhora o throughput em 10-30%. Para rede local estável: diferença mínima.

Não, sudo sysctl -p /etc/sysctl.d/99-vps-performance.conf aplica imediatamente sem reboot. O arquivo garante que as mudanças persistem após reinicialização. Exceção: limites do ulimit para processos já em execução requerem restart do serviço. Para aplicar os limites do limits.conf em serviços systemd: sudo systemctl daemon-reload + restart do serviço.