Load Shedding no Node.js é a prática de rejeitar trabalho de forma controlada quando a aplicação se aproxima da saturação. Em vez de aceitar tudo, aumentar filas e falhar lentamente, o sistema preserva capacidade para operações prioritárias e responde rapidamente aos demais pedidos.
O objetivo não é esconder falta de recursos. É impedir que sobrecarga temporária se transforme em colapso, timeouts em cascata e reinicializações.
Sinais de saturação
- event loop lag elevado;
- CPU próxima do limite;
- heap crescendo rapidamente;
- fila de requisições longa;
- pool de conexões esgotado;
- latência acima do SLO;
- muitas operações em timeout.
Rejeição simples por concorrência
let active = 0;
const MAX_ACTIVE = 200;
async function handler(req, res) {
if (active >= MAX_ACTIVE) {
res.writeHead(503, { 'Retry-After': '1' });
res.end('Temporarily unavailable');
return;
}
active++;
try {
await processRequest(req, res);
} finally {
active--;
}
}O limite deve ser medido e testado. Um valor alto demais não protege; um valor baixo demais desperdiça capacidade.
Fila limitada
Quando uma operação precisa esperar, imponha tamanho e tempo máximos. Itens expirados devem ser removidos antes de consumir recursos.
if (queue.length >= MAX_QUEUE) {
throw new Error('OVERLOADED');
}Prioridade de tráfego
Reserve capacidade para operações essenciais. Por exemplo, confirmação de pagamento pode ter prioridade maior que geração de relatório. Use filas separadas ou cotas por classe.
Load shedding por tenant
Limites por tenant impedem que um único cliente monopolize o sistema. Combine taxa, concorrência e custo estimado da operação. Veja Multi-Tenancy no Node.js.
Event loop lag
O Node.js pode continuar aceitando conexões mesmo quando o event loop está atrasado. Meça o atraso para detectar saturação de CPU.
import { monitorEventLoopDelay } from 'node:perf_hooks';
const lag = monitorEventLoopDelay({ resolution: 20 });
lag.enable();
function overloaded() {
return lag.percentile(99) / 1e6 > 100;
}Consulte perf_hooks no Node.js.
Memória e pressão do heap
Não espere chegar ao limite de memória. Ao detectar crescimento anormal, reduza tarefas pesadas, pause consumidores e rejeite uploads grandes. Load shedding não substitui correção de vazamentos.
Protegendo dependências
Quando banco ou API externa está degradada, reduzir entrada evita multiplicar timeouts. Circuit breakers e bulkheads complementam essa estratégia.
Veja Circuit Breaker no Node.js e Bulkhead Pattern no Node.js.
HTTP correto
Use 503 Service Unavailable para indisponibilidade temporária e 429 Too Many Requests para limites atribuídos ao cliente. Inclua Retry-After apenas quando puder oferecer uma estimativa útil.
Não faça retry imediato
Clientes devem usar backoff com jitter. Repetições sincronizadas podem criar uma nova onda de carga maior que a original.
Consumidores de fila
Pause o consumo quando banco, CPU ou memória estão saturados. Ajuste prefetch e concorrência dinamicamente dentro de limites seguros. Não continue retirando mensagens se não há capacidade de processá-las.
Degradação funcional
Em vez de rejeitar toda a requisição, alguns sistemas podem desativar recursos opcionais:
- responder sem recomendações;
- usar dados em cache;
- adiar auditoria não crítica via Outbox;
- reduzir resolução de imagens;
- desabilitar cálculo caro.
Histerese
Evite alternar rapidamente entre estados normal e sobrecarregado. Entre em shedding acima de um limite e só saia quando a métrica cair para um patamar menor por algum tempo.
Observabilidade
Monitore:
- requisições rejeitadas por motivo;
- classe de prioridade;
- event loop lag;
- tempo em fila;
- CPU, heap e conexões;
- latência antes e depois do shedding;
- efeito nos SLOs.
Testes de carga
Valide o comportamento acima da capacidade nominal. O sistema deve rejeitar cedo, manter latência previsível para tráfego prioritário e se recuperar quando a carga cair.
Erros comuns
- fila ilimitada;
- rejeitar somente após o timeout;
- não diferenciar tráfego crítico;
- usar CPU como único sinal;
- clientes fazendo retry imediato;
- limite global sem cotas por tenant;
- não testar recuperação.
Conclusão
Load Shedding no Node.js preserva a saúde da aplicação ao recusar trabalho antes da saturação completa. A técnica funciona melhor com filas limitadas, prioridades, deadlines, bulkheads e sinais reais de capacidade.
Defina políticas explícitas e teste em carga. Consulte a documentação de perf_hooks e a documentação HTTP do Node.js.




