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

k6 no Node.js

Atualizado em: 26 de setembro de 2026

Rack de servidores processando fluxos de dados no Node.js

k6 é uma ferramenta de testes de carga que usa scripts JavaScript para descrever tráfego, cenários, checks e limites de desempenho. Embora o script seja escrito em JavaScript, ele não executa dentro do Node.js: k6 possui runtime próprio. Por isso, módulos e APIs precisam ser compatíveis com a plataforma k6.

Em aplicações Node.js, k6 é útil para validar APIs HTTP, gRPC, WebSocket e fluxos de usuário sob smoke, carga média, stress, spike, soak e breakpoint. Ele pode rodar localmente, em containers, Kubernetes ou Grafana Cloud.

Instalação

Use o pacote oficial do sistema ou Docker:

docker run --rm -i grafana/k6 run - < load-test.js

Também é possível instalar o binário conforme o sistema operacional. Fixe a versão em CI para evitar diferenças entre execuções.

Primeiro script

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 10,
  duration: '30s',
};

export default function () {
  const response = http.get('http://host.docker.internal:3000/health');

  check(response, {
    'status é 200': (res) => res.status === 200,
    'resposta abaixo de 200 ms': (res) => res.timings.duration < 200,
  });

  sleep(1);
}

Execute:

k6 run load-test.js

Init context e VU code

Código fora da função padrão roda na inicialização de cada VU. Use-o para opções, dados compartilhados e definições. A função default é repetida conforme o executor.

Não coloque autenticação única ou setup caro no corpo se pode ser feito uma vez no setup().

Virtual users

VUs são loops paralelos que executam o cenário. Mais VUs não correspondem diretamente a usuários reais sem considerar tempo de espera, duração das requisições e comportamento.

Calcule um modelo baseado na taxa de chegada ou na concorrência esperada.

Stages

export const options = {
  stages: [
    { duration: '30s', target: 20 },
    { duration: '2m', target: 20 },
    { duration: '30s', target: 0 },
  ],
};

Essa configuração aquece, mantém carga e reduz. Para controle avançado, use scenarios.

Scenarios

export const options = {
  scenarios: {
    leitura: {
      executor: 'constant-arrival-rate',
      rate: 200,
      timeUnit: '1s',
      duration: '2m',
      preAllocatedVUs: 20,
      maxVUs: 100,
      exec: 'readItems',
    },
    escrita: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '30s', target: 10 },
        { duration: '1m', target: 10 },
        { duration: '20s', target: 0 },
      ],
      exec: 'createItem',
    },
  },
};

export function readItems() {}
export function createItem() {}

Cenários permitem cargas independentes e proporções mais realistas.

Modelo fechado e aberto

Executores por VU representam modelo fechado: novas iterações dependem da conclusão anterior. Arrival-rate representa modelo aberto: requisições chegam em taxa definida. Para APIs públicas, o modelo aberto costuma revelar melhor degradação e filas.

Checks

check(response, {
  'status correto': (r) => r.status === 200,
  'json válido': (r) => r.json('id') !== undefined,
});

Checks registram sucesso, mas não fazem o teste falhar automaticamente. Use thresholds.

Thresholds

export const options = {
  thresholds: {
    http_req_failed: ['rate<0.01'],
    http_req_duration: ['p(95)<300', 'p(99)<800'],
    checks: ['rate>0.99'],
  },
};

Se um threshold falha, k6 retorna código de saída diferente de zero, permitindo bloquear pipeline.

Métricas principais

  • http_req_duration: duração total;
  • http_req_waiting: tempo até primeiro byte;
  • http_req_failed: taxa de falhas;
  • iterations: iterações concluídas;
  • vus: usuários ativos;
  • dropped_iterations: carga que não conseguiu ser iniciada;
  • data_received e data_sent.

POST com JSON

const payload = JSON.stringify({
  name: `user-${__VU}-${__ITER}`,
  email: `user-${__VU}-${__ITER}@example.com`,
});

const response = http.post(`${baseUrl}/users`, payload, {
  headers: {
    'Content-Type': 'application/json',
  },
});

Use identificadores únicos e ambiente descartável para não acumular colisões.

Variáveis de ambiente

k6 run -e BASE_URL=https://staging.example.com load-test.js
const baseUrl = __ENV.BASE_URL;

Não grave tokens em scripts. Injete por secret e evite imprimir.

Setup e teardown

export function setup() {
  const response = http.post(`${baseUrl}/sessions`, JSON.stringify({
    username: __ENV.USERNAME,
    password: __ENV.PASSWORD,
  }), { headers: { 'Content-Type': 'application/json' } });

  return { token: response.json('token') };
}

export default function (data) {
  http.get(`${baseUrl}/profile`, {
    headers: { Authorization: `Bearer ${data.token}` },
  });
}

export function teardown(data) {
  // limpeza opcional
}

Dados retornados por setup são serializados para VUs. Evite objetos grandes.

SharedArray

Para carregar dados uma vez:

import { SharedArray } from 'k6/data';

const users = new SharedArray('users', () =>
  JSON.parse(open('./users.json')),
);

Não carregue um arquivo separado para cada VU.

Tags e grupos

import { group } from 'k6';

group('checkout', () => {
  http.get(`${baseUrl}/cart`, { tags: { endpoint: 'cart' } });
  http.post(`${baseUrl}/checkout`, null, { tags: { endpoint: 'checkout' } });
});

Tags permitem thresholds por rota:

'http_req_duration{endpoint:checkout}': ['p(95)<500']

Sleep e think time

Usuários reais não enviam requisições continuamente. Adicione pausa quando o cenário representa jornada. Em testes de capacidade pura, talvez não seja necessário.

HTTP batch

const responses = http.batch([
  ['GET', `${baseUrl}/profile`],
  ['GET', `${baseUrl}/notifications`],
  ['GET', `${baseUrl}/preferences`],
]);

Batch simula requisições paralelas, mas pode aumentar carga de forma diferente do cliente real.

gRPC e WebSocket

k6 possui APIs para gRPC e WebSocket. Defina métricas e checks específicos, incluindo mensagens, duração de conexão e erros.

Smoke test

export const options = {
  vus: 1,
  duration: '30s',
  thresholds: {
    http_req_failed: ['rate==0'],
  },
};

Rode em cada deploy para verificar script e ambiente.

Average load

Use tráfego típico, dados representativos e duração suficiente para estabilizar cache, pools e GC. Esse cenário define baseline.

Stress e breakpoint

Aumente carga gradualmente até SLO falhar. Observe onde latência cresce, erros aparecem e recursos saturam. Interrompa antes de danificar dados ou infraestrutura compartilhada.

Spike

Suba rapidamente para validar autoscaling, filas e proteção. Compare tempo de recuperação após o pico.

Soak

Execute por horas para encontrar vazamentos de memória, crescimento de filas, conexões abandonadas e degradação de cache.

Docker

docker run --rm \
  -i \
  -e BASE_URL=http://host.docker.internal:3000 \
  grafana/k6 run - < load-test.js

Em Linux, configure acesso ao host ou use rede adequada.

CI

- name: Smoke performance
  run: |
    docker run --rm -i \
      -e BASE_URL="$BASE_URL" \
      grafana/k6:VERSAO run - < test/k6/smoke.js

Fixe a imagem. Benchmarks precisos não devem depender de runner compartilhado; smoke e thresholds amplos funcionam bem.

Kubernetes Operator

Para carga distribuída, k6 Operator executa TestRun com paralelismo. Dimensione geradores e monitore se eles próprios saturam.

Resultados

k6 envia métricas para JSON, Prometheus remote write, InfluxDB, Grafana Cloud e outras saídas. Correlacione carga com métricas do serviço.

Custom metrics

import { Trend, Rate } from 'k6/metrics';

const checkoutDuration = new Trend('checkout_duration');
const businessErrors = new Rate('business_errors');

checkoutDuration.add(response.timings.duration);
businessErrors.add(response.status !== 201);

Cardinalidade

Não use ID único como tag. Isso cria séries demais e pode sobrecarregar backend de métricas. Tags devem ter conjunto limitado.

Dados e segurança

Execute em ambiente autorizado, use contas de teste, limite custos e proteja segredos. Testes de carga são tráfego destrutivo em potencial.

k6 ou Autocannon

Autocannon é ótimo para benchmark HTTP local e API programática Node.js. k6 oferece cenários, thresholds, execução distribuída, jornadas e integrações de observabilidade. Muitas equipes usam os dois.

Fluxo recomendado

Comece com smoke, estabeleça baseline, defina SLOs como thresholds, modele chegada real, observe aplicação e repita em ambiente controlado. Combine com Autocannon no Node.js, métricas em Prometheus, autoscaling em Kubernetes HPA e alertas em Alertmanager.

Consulte a documentação oficial para executar k6 e o guia oficial de thresholds.

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