Otimização de Performance
Este documento detalha como otimizar performance do n8n para máxima eficiência, incluindo configuração de workers, ajuste de timeouts, otimização de queries de banco, gerenciamento de memória, monitoramento de recursos, e técnicas avançadas de tuning que maximizam throughput e minimizam latência em workflows de alta demanda para operações empresariais críticas.
Configuração de Workers
Docker Compose Otimizado
version: '3.8'
services:
# Worker principal
n8n-main:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- EXECUTIONS_PROCESS=main
- EXECUTIONS_MODE=regular
- REDIS_URL=redis://redis:6379
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- EXECUTIONS_TIMEOUT=300000
- EXECUTIONS_TIMEOUT_MAX=3600000
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
depends_on:
- postgres
- redis
networks:
- n8n_network
# Workers de execução otimizados
n8n-worker-1:
image: n8nio/n8n:latest
restart: unless-stopped
environment:
- EXECUTIONS_PROCESS=worker
- EXECUTIONS_MODE=regular
- REDIS_URL=redis://redis:6379
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- EXECUTIONS_TIMEOUT=300000
- EXECUTIONS_TIMEOUT_MAX=3600000
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
depends_on:
- postgres
- redis
networks:
- n8n_network
n8n-worker-2:
image: n8nio/n8n:latest
restart: unless-stopped
environment:
- EXECUTIONS_PROCESS=worker
- EXECUTIONS_MODE=regular
- REDIS_URL=redis://redis:6379
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- EXECUTIONS_TIMEOUT=300000
- EXECUTIONS_TIMEOUT_MAX=3600000
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
depends_on:
- postgres
- redis
networks:
- n8n_network
# Banco de dados otimizado
postgres:
image: postgres:15
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgresql.conf:/etc/postgresql/postgresql.conf
command: postgres -c config_file=/etc/postgresql/postgresql.conf
deploy:
resources:
limits:
memory: 4G
cpus: '2.0'
reservations:
memory: 2G
cpus: '1.0'
networks:
- n8n_network
# Redis otimizado
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --appendonly yes --maxmemory 1gb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
deploy:
resources:
limits:
memory: 1G
cpus: '0.5'
reservations:
memory: 512M
cpus: '0.25'
networks:
- n8n_network
volumes:
postgres_data:
redis_data:
networks:
n8n_network:
driver: bridge
Otimização de Timeouts
Configuração de Timeouts
# Timeouts por tipo de operação
EXECUTIONS_TIMEOUT=300000 # 5 minutos para execuções normais
EXECUTIONS_TIMEOUT_MAX=3600000 # 1 hora para execuções longas
WEBHOOK_TIMEOUT=120000 # 2 minutos para webhooks
API_TIMEOUT=60000 # 1 minuto para APIs
Otimização de Banco de Dados
PostgreSQL Otimizado
# postgresql.conf - Otimizações
# Logs
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_min_duration_statement = 1000 # Log queries > 1s
# Performance
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
# Connections
max_connections = 100
Script de Manutenção
#!/bin/bash
# Configurações
DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="n8n"
DB_USER="n8n"
echo "=== Manutenção do Banco de Dados ==="
echo
echo "1. Executando VACUUM e ANALYZE..."
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "VACUUM ANALYZE;"
echo
echo "2. Reindexando tabelas..."
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "REINDEX DATABASE $DB_NAME;"
echo
echo "3. Atualizando estatísticas..."
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "ANALYZE;"
echo
echo "4. Limpando execuções antigas..."
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "
DELETE FROM executions
WHERE created_at < NOW() - INTERVAL '30 days'
AND status IN ('success', 'error');"
echo
echo "Manutenção concluída!"
Otimização de Memória
Configuração Node.js
# Variáveis de ambiente para otimização de memória
NODE_OPTIONS="--max-old-space-size=4096 --max-semi-space-size=512"
# Docker com otimizações de memória
docker run -e NODE_OPTIONS="--max-old-space-size=4096" n8nio/n8n
Configuração de Memória Redis
# redis.conf - Otimizações de memória
maxmemory 1gb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
Monitoramento de Memória
#!/bin/bash
echo "=== Monitoramento de Memória ==="
echo
echo "1. Memória do Sistema:"
free -h
echo
echo "2. Memória dos Containers:"
docker stats --no-stream --format "table {{.Container}}\t{{.MemUsage}}\t{{.MemPerc}}"
echo
echo "3. Memória do Node.js:"
for container in n8n-main n8n-worker-1 n8n-worker-2; do
echo "=== $container ==="
docker exec $container node -e "
const mem = process.memoryUsage();
console.log('RSS:', Math.round(mem.rss / 1024 / 1024) + 'MB');
console.log('Heap Used:', Math.round(mem.heapUsed / 1024 / 1024) + 'MB');
console.log('Heap Total:', Math.round(mem.heapTotal / 1024 / 1024) + 'MB');
"
done
echo
echo "4. Memória Redis:"
redis-cli info memory | grep -E "(used_memory_human|maxmemory_human)"
echo
echo "5. Alertas de Memória:"
MEMORY_THRESHOLD=85
for container in n8n-main n8n-worker-1 n8n-worker-2; do
MEMORY_PERC=$(docker stats --no-stream --format "{{.MemPerc}}" $container | sed 's/%//')
if (( $(echo "$MEMORY_PERC > $MEMORY_THRESHOLD" | bc -l) )); then
echo "⚠️ ALERTA: $container usando $MEMORY_PERC% de memória"
fi
done
Monitoramento de Performance
Métricas de Performance
#!/bin/bash
echo "=== Métricas de Performance ==="
echo
echo "1. Uso de Recursos:"
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
echo
echo "2. Execuções por Minuto:"
EXECUTIONS_PER_MIN=$(psql -h localhost -U n8n -d n8n -t -c "
SELECT COUNT(*) FROM executions
WHERE created_at > NOW() - INTERVAL '1 minute';")
echo "Execuções no último minuto: $EXECUTIONS_PER_MIN"
echo
echo "3. Tempo Médio de Execução:"
AVG_EXECUTION_TIME=$(psql -h localhost -U n8n -d n8n -t -c "
SELECT AVG(EXTRACT(EPOCH FROM (finished_at - started_at)))
FROM executions
WHERE finished_at IS NOT NULL
AND created_at > NOW() - INTERVAL '1 hour';")
echo "Tempo médio (última hora): ${AVG_EXECUTION_TIME}s"
echo
echo "4. Taxa de Erro:"
ERROR_RATE=$(psql -h localhost -U n8n -d n8n -t -c "
SELECT
ROUND(
(COUNT(CASE WHEN status = 'error' THEN 1 END) * 100.0 / COUNT(*)), 2
) as error_rate
FROM executions
WHERE created_at > NOW() - INTERVAL '1 hour';")
echo "Taxa de erro (última hora): ${ERROR_RATE}%"
echo
echo "5. Status das Filas:"
echo "Jobs na fila: $(redis-cli llen n8n:queue:jobs)"
echo "Webhooks na fila: $(redis-cli llen n8n:queue:webhooks)"
echo "Jobs processados: $(redis-cli get n8n:stats:processed || echo '0')"
echo "Jobs falharam: $(redis-cli get n8n:stats:failed || echo '0')"
Alertas de Performance
#!/bin/bash
# Configurações
CPU_THRESHOLD=80
MEMORY_THRESHOLD=85
ERROR_RATE_THRESHOLD=10
EXECUTION_TIME_THRESHOLD=300
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
# Verificar CPU
for container in n8n-main n8n-worker-1 n8n-worker-2; do
CPU_USAGE=$(docker stats --no-stream --format "{{.CPUPerc}}" $container | sed 's/%//')
if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc -l) )); then
curl -X POST $WEBHOOK_URL \
-H "Content-type: application/json" \
-d "{\"text\":\"⚠️ CPU alta em $container: ${CPU_USAGE}%\"}"
fi
done
# Verificar memória
for container in n8n-main n8n-worker-1 n8n-worker-2; do
MEMORY_USAGE=$(docker stats --no-stream --format "{{.MemPerc}}" $container | sed 's/%//')
if (( $(echo "$MEMORY_USAGE > $MEMORY_THRESHOLD" | bc -l) )); then
curl -X POST $WEBHOOK_URL \
-H "Content-type: application/json" \
-d "{\"text\":\"⚠️ Memória alta em $container: ${MEMORY_USAGE}%\"}"
fi
done
# Verificar taxa de erro
ERROR_RATE=$(psql -h localhost -U n8n -d n8n -t -c "
SELECT ROUND((COUNT(CASE WHEN status = 'error' THEN 1 END) * 100.0 / COUNT(*)), 2)
FROM executions
WHERE created_at > NOW() - INTERVAL '10 minutes';" | xargs)
if (( $(echo "$ERROR_RATE > $ERROR_RATE_THRESHOLD" | bc -l) )); then
curl -X POST $WEBHOOK_URL \
-H "Content-type: application/json" \
-d "{\"text\":\"🚨 Taxa de erro alta: ${ERROR_RATE}%\"}"
fi
# Verificar tempo de execução
AVG_TIME=$(psql -h localhost -U n8n -d n8n -t -c "
SELECT AVG(EXTRACT(EPOCH FROM (finished_at - started_at)))
FROM executions
WHERE finished_at IS NOT NULL
AND created_at > NOW() - INTERVAL '10 minutes';" | xargs)
if (( $(echo "$AVG_TIME > $EXECUTION_TIME_THRESHOLD" | bc -l) )); then
curl -X POST $WEBHOOK_URL \
-H "Content-type: application/json" \
-d "{\"text\":\"🐌 Tempo de execução alto: ${AVG_TIME}s\"}"
fi
Técnicas Avançadas de Tuning
Otimização de Workflows
// 1. Usar batch processing para grandes volumes
const batchSize = 100;
const items = await getItems();
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
await processBatch(batch);
}
// 2. Implementar cache para dados frequentes
const cache = new Map();
async function getCachedData(key) {
if (cache.has(key)) {
return cache.get(key);
}
const data = await fetchData(key);
cache.set(key, data);
return data;
}
// 3. Usar paralelismo quando possível
const promises = items.map(item => processItem(item));
const results = await Promise.all(promises);
// 4. Implementar retry com backoff exponencial
async function retryWithBackoff(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, i) * 1000)
);
}
}
}
Otimização de Rede
# Otimizações de rede para Linux
# /etc/sysctl.conf
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
Troubleshooting de Performance
#!/bin/bash
echo "=== Diagnóstico de Performance ==="
echo
echo "1. Logs de performance:"
docker logs n8n-main | grep -E "(slow|timeout|error)"
echo
echo "2. Queries lentas do banco:"
psql -h localhost -U n8n -d n8n -c "
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;"
echo
echo "3. Memory leaks:"
for container in n8n-main n8n-worker-1 n8n-worker-2; do
echo "=== $container ==="
docker exec $container node -e "
const mem = process.memoryUsage();
console.log('RSS:', Math.round(mem.rss / 1024 / 1024) + 'MB');
console.log('Heap Used:', Math.round(mem.heapUsed / 1024 / 1024) + 'MB');
"
done
echo
echo "4. GC analysis:"
docker exec n8n-main node --trace-gc -e "console.log('GC test')"
Problemas Comuns
#!/bin/bash
echo "=== Problemas Comuns de Performance ==="
echo
echo "1. Timeouts frequentes:"
docker exec n8n-main env | grep -E "(TIMEOUT|EXECUTIONS)"
echo
echo "2. Memory leaks:"
docker stats --no-stream --format "table {{.Container}}\t{{.MemUsage}}\t{{.MemPerc}}"
echo
echo "3. CPU spikes:"
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}"
echo
echo "4. Network issues:"
netstat -i
echo
echo "5. Disk I/O:"
iostat -x 1 3
Checklist de Otimização
Configuração
- Workers configurados adequadamente
- Timeouts otimizados
- Memória alocada corretamente
- Redis configurado para performance
- Banco de dados otimizado
Monitoramento
- Métricas de performance configuradas
- Alertas configurados
- Logs estruturados
- Dashboard de monitoramento
- Health checks implementados
Otimização
- Queries de banco otimizadas
- Cache implementado
- Batch processing configurado
- Paralelismo utilizado
- Retry policies definidas
Manutenção
- Limpeza automática de dados antigos
- Backup configurado
- Log rotation ativado
- Monitoramento de recursos
- Alertas de performance
Dica Pro
Monitore constantemente as métricas de performance e ajuste as configurações conforme necessário. Use ferramentas como Prometheus e Grafana para visualização avançada.
Importante
Sempre teste otimizações de performance em ambiente de desenvolvimento antes de aplicar em produção. Monitore o impacto das mudanças.