Pular para o conteúdo

Voltar para o blog

Node.js

Perfilando Node.js em produção sem overhead

· 8 min

Profiling em produção assusta porque as ferramentas mais conhecidas, instrumentar cada chamada de função, adicionam overhead suficiente pra mudar exatamente o comportamento que se quer medir. A boa notícia é que essa não é a única forma de perfilar um processo Node.js rodando de verdade.

Ilustração de uma chama

Instrumentação: precisa, mas cara

Profiling por instrumentação envolve envolver cada chamada de função com código que registra entrada e saída, dando contagens e durações exatas. O problema é que esse próprio envolvimento tem custo, e pra funções pequenas e muito chamadas esse custo pode dominar o tempo medido, distorcendo o custo relativo entre as partes do código.

Amostragem: aproximado, mas barato

Profilers por amostragem, o `--prof` embutido no V8, ferramentas baseadas em `perf`, interrompem o processo periodicamente (a cada poucos milissegundos) e registram a call stack naquele instante, construindo um retrato estatístico de onde o tempo é gasto sem tocar o código em si. O overhead depende da frequência de amostragem, não do tamanho do código, então fica baixo e previsível mesmo em produção.

De volta pra um flame graph legível

As amostras brutas de call stack viram um flame graph agregando stacks repetidas numa árvore, onde a largura de cada bloco representa o tempo gasto ali. Ferramentas como clinic.js flame e 0x automatizam esse processo inteiro em Node, direto contra um processo já rodando, sem precisar reiniciar nada.

O que rodar em produção de verdade

Na prática, o ideal é acionar profiling por amostragem sob demanda, via sinal (SIGUSR2 pra alternar o profiler do V8) ou uma flag como `--cpu-prof`, por uma janela curta e específica, em vez de deixar um profiler ligado permanentemente. E comparar sempre contra uma execução de baseline sem profiling, pra confirmar que o overhead continuou desprezível.