Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

CPU Profiling com –prof no Node.js

Atualizado em: 27 de setembro de 2026

Rack de servidores processando fluxos de dados no Node.js

O Node.js inclui um profiler de CPU baseado no V8 que pode ser ativado com a opção --prof. Ele coleta amostras enquanto a aplicação executa e grava um arquivo de log contendo informações sobre JavaScript, código nativo, garbage collection e bibliotecas do sistema. Esse recurso é útil quando a aplicação apresenta CPU alta, throughput baixo, event loop bloqueado ou uma regressão que não aparece claramente nos logs.

O profiler integrado reduz a necessidade de instalar uma ferramenta adicional para uma primeira investigação. Ainda assim, ele deve ser usado com método: é preciso reproduzir o problema, gerar carga representativa, processar o log e validar qualquer otimização com uma nova medição.

Quando usar o –prof

O profiling por amostragem é indicado quando a pergunta principal é “onde o processo gasta tempo de CPU?”. Exemplos:

  • uma rota fica lenta sob concorrência;
  • o processo alcança 100% de um núcleo;
  • p95 e p99 aumentam sem crescimento proporcional no banco;
  • serialização de respostas grandes parece cara;
  • regex, criptografia ou compressão bloqueiam a thread;
  • uma nova versão reduziu requisições por segundo;
  • garbage collection consome uma parcela relevante da CPU.

Para investigar memória retida, use heap snapshots. Para cadeias assíncronas lentas, combine o perfil com traces, Async Hooks ou Clinic Bubbleprof.

Executando o primeiro perfil

Inicie a aplicação com:

node --prof dist/server.js

O V8 criará um arquivo semelhante a:

isolate-0x123456789-12345-v8.log

Enquanto o processo executa, gere carga em outro terminal:

npx autocannon -c 40 -d 45 http://127.0.0.1:3000/api/items

Espere o cenário lento acontecer e encerre o servidor de forma controlada. Uma captura muito curta possui poucas amostras; uma captura longa pode misturar inicialização, períodos ociosos e diferentes tipos de tráfego.

Processando o log

O arquivo bruto não é agradável de ler. Processe-o com:

node --prof-process isolate-0x123456789-12345-v8.log > profile.txt

O relatório inclui seções de ticks, código JavaScript, C++, bibliotecas compartilhadas e perfil pesado. O nome exato das seções pode variar conforme a plataforma e a versão do runtime.

Entendendo ticks

Um tick representa uma amostra periódica da pilha de execução. Quanto mais ticks uma função acumula, maior a parcela estimada de CPU associada a ela. O resultado é estatístico, não uma medição exata de cada chamada.

Procure funções com porcentagem alta e confirme se aparecem em pilhas relevantes. Uma função chamadora pode acumular tempo inclusivo porque executa descendentes caros; a causa real costuma estar em uma função folha.

Perfil pesado

A seção “Bottom up (heavy) profile” organiza amostras começando pelas funções que consumiram CPU. Ela ajuda a responder quais caminhos de chamada dominam o processamento.

Observe:

  • funções JavaScript do projeto;
  • JSON.stringify e parsing;
  • ordenação de grandes coleções;
  • funções de regex;
  • hash, assinatura e criptografia;
  • compressão;
  • garbage collector;
  • addons nativos;
  • funções desconhecidas ou sem símbolos.

Exemplo de CPU síncrona

import { createServer } from 'node:http';
import { pbkdf2Sync } from 'node:crypto';

const server = createServer((req, res) => {
  if (req.url === '/hash') {
    const hash = pbkdf2Sync('senha', 'salt', 300000, 32, 'sha256');
    res.end(hash.toString('hex'));
    return;
  }

  res.end('ok');
});

server.listen(3000);

Com várias requisições simultâneas, pbkdf2Sync bloqueia a thread principal. O perfil deve concentrar amostras na pilha de criptografia. A correção pode usar a versão assíncrona, uma fila ou Worker Threads. Não reduza parâmetros de segurança apenas para melhorar um benchmark.

Exemplo de serialização cara

function gerarResposta(items) {
  return JSON.stringify({
    generatedAt: new Date().toISOString(),
    items: items.map(normalizarItem),
  });
}

Se a lista possui milhares de objetos, normalização e serialização podem dominar CPU. Alternativas incluem paginação, redução de campos, cache de conteúdo estável, streaming ou pré-processamento.

Aquecimento do V8

O V8 otimiza funções quentes durante a execução. Um perfil iniciado imediatamente após o bootstrap pode mostrar compilação, carregamento de módulos e caches frios, em vez do comportamento estável.

  1. inicie a aplicação;
  2. espere conexões e pools ficarem prontos;
  3. execute uma carga de aquecimento;
  4. comece o cenário medido;
  5. mantenha carga constante;
  6. encerre depois de coletar amostras suficientes.

Comparando versões

Para medir uma otimização, mantenha constantes:

  • versão do Node.js;
  • hardware e limites de CPU;
  • conjunto de dados;
  • concorrência e duração;
  • estado de cache;
  • variáveis de ambiente;
  • gerador de carga;
  • rota e payload.

Compare o perfil junto com throughput, p95, p99, erros, CPU total e event loop delay. Uma função pode ficar menor enquanto o custo migra para outra etapa.

Profiling em produção

O profiler adiciona overhead e gera um arquivo que pode revelar nomes de funções, caminhos e arquitetura interna. Em produção:

  • capture somente uma réplica;
  • use uma janela curta;
  • monitore latência e CPU durante a captura;
  • grave em diretório com espaço suficiente;
  • proteja e remova o arquivo após a análise;
  • não exponha uma rota pública para iniciar profiling;
  • registre a operação em auditoria.

Quando possível, reproduza em staging com uma carga semelhante. Se o incidente só acontece em produção, isole o processo e prepare um plano de rollback.

Containers e Kubernetes

Em containers, persista o log em volume ou copie o arquivo antes que o pod seja removido. Registre requests, limits e throttling, porque uma aplicação limitada por cgroup pode parecer mais lenta mesmo sem mudança de código.

FROM node:24-alpine
WORKDIR /app
COPY . .
CMD ["node", "--prof", "dist/server.js"]

Não mantenha o profiler ativado permanentemente em todas as réplicas. Use uma imagem ou comando temporário de diagnóstico.

Funções sem nome e símbolos

Frames desconhecidos podem surgir por código otimizado, bibliotecas nativas, símbolos ausentes ou limitações da plataforma. Compare o resultado com um flamegraph, 0x, Linux perf ou Clinic Flame. Ferramentas diferentes podem revelar perspectivas complementares.

Garbage collection

Se o relatório mostra muita CPU em GC, investigue a taxa de alocação. Objetos temporários, cópias de arrays, buffers e serialização podem pressionar o coletor mesmo sem vazamento.

Combine com métricas de process.memoryUsage(), traces de GC e heap profiler. Aumentar o limite do heap pode apenas adiar pausas e tornar o processo maior.

Automatizando a captura

Um script pode nomear arquivos por commit e cenário:

mkdir -p diagnostics
NODE_OPTIONS="--prof" node dist/server.js
mv isolate-*-v8.log "diagnostics/${GIT_SHA:-local}-v8.log"

Garanta que somente um processo grave no diretório ou use subpastas por PID. Em cluster e Worker Threads, diferentes isolates podem gerar logs separados.

Erros comuns

  • capturar enquanto a aplicação está ociosa;
  • não aquecer o runtime;
  • usar uma carga diferente no teste posterior;
  • olhar somente a função com maior porcentagem;
  • confundir tempo inclusivo e exclusivo;
  • otimizar sem medir percentis;
  • ignorar CPU do gerador de carga;
  • compartilhar logs de profiling publicamente;
  • concluir que toda CPU alta é um problema de JavaScript.

Fluxo recomendado

  1. confirme o sintoma com métricas;
  2. formule uma hipótese;
  3. reproduza com carga estável;
  4. capture com --prof;
  5. processe com --prof-process;
  6. localize pilhas dominantes;
  7. faça uma alteração pequena;
  8. repita o benchmark e o perfil;
  9. documente os números antes e depois.

Combine o profiler integrado com Flamegraphs no Node.js, diagnóstico visual em Clinic.js, carga com Autocannon e cenários com k6.

Consulte a referência oficial da opção –prof e o guia oficial de flamegraphs do Node.js.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita