Skip to main content
26 may 2026ejemplos umbrales k6

Por Performate

Ejemplos de umbrales en k6: alerta sobre las métricas que importan

Patrones concretos de umbrales k6 para percentiles de latencia, tasas de error y métricas custom—y cómo los códigos de salida convierten corridas en puertas de CI.

La corrida terminó con p(99)=2.1s y nadie sabe si eso es pass o fail. El equipo debate el gráfico veinte minutos, mergea igual, y el viernes producción viola el SLO que «visualmente se veía bien» en staging.

Los umbrales en k6 convierten la salida de interesante a accionable: definen pass/fail sobre métricas agregadas, fijan el código de salida al violarlos, y cablean pruebas de carga como puertas reales en CI. En esta guía verás patrones concretos para latencia global, rutas por tag, métricas custom y abort temprano—y cómo interpretar fallos sin confundir saturación con bugs funcionales.

Por qué los umbrales cambian decisiones—no solo reportes

A nivel visual, un gráfico de latencia siempre « cuenta una historia ». Sin criterios explícitos:

  • Debate sin cierrep95 en 380 ms puede ser victoria o desastre según el endpoint; sin número acordado, gana la intuición.
  • Agregación engañosa — mezclar checkout lento y catálogo rápido en un solo http_req_duration oculta regresiones en el camino crítico.
  • Errores vs latencia — HTTP 200 con body de error de negocio pasa checks de status pero viola conversión; hace falta métricas custom.
  • CI sin dientes — k6 exit code 0 con umbrales vacíos = pipeline verde que no protege releases.

Lee p95 vs p99 latencia antes de elegir percentiles, y pruebas de carga en CI/CD al cablear fallos en pipelines (thresholds documentation).

Implementación práctica con k6: umbrales globales, por tag y abortOnFail

Combina umbrales globales para smoke, filtros por tag para rutas críticas, y abortOnFail cuando el sistema ya está derretido.

Script de ejemplo (ilustrativo—no es una prueba lista para producción). El snippet usa URLs, SLO y tags ficticios. Adapta base URL, auth y límites a tu entorno.

Qué demuestra este ejemplo:

  • Patrón A — global: http_req_duration y http_req_failed para smoke de salud general.
  • Patrón B — por ruta: umbrales en http_req_duration{route:checkout} más estrictos que catálogo.
  • Patrón C — custom: Rate sobre errores de negocio devueltos como HTTP 200.
  • Patrón D — abort: abortOnFail en error rate evita quemar staging 30 minutos cuando ya falló.
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';

const BASE = __ENV.API_BASE || 'https://staging.example.com';
const businessErrors = new Rate('business_errors');

export const options = {
  scenarios: {
    mixed_routes: {
      executor: 'constant-arrival-rate',
      rate: 40,
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 20,
      maxVUs: 80,
      exec: 'mixedFlow',
    },
  },
  thresholds: {
    // Patrón A: global
    http_req_duration: ['p(95)<500'],
    http_req_failed: ['rate<0.01', { abortOnFail: true, delayAbortEval: '30s' }],

    // Patrón B: por tag de ruta
    'http_req_duration{route:checkout}': ['p(95)<700', 'p(99)<1200'],
    'http_req_duration{route:catalog}': ['p(95)<250'],

    // Patrón C: métrica custom
    business_errors: ['rate<0.005'],
  },
};

export function mixedFlow() {
  const headers = { Authorization: `Bearer ${__ENV.TOKEN}` };

  const catalog = http.get(`${BASE}/v1/catalog?page=1`, {
    headers,
    tags: { route: 'catalog' },
  });
  check(catalog, { 'catalog 2xx': (r) => r.status === 200 });

  const checkout = http.post(
    `${BASE}/v1/checkout`,
    JSON.stringify({ sku: 'SKU-100', qty: 1 }),
    { headers, tags: { route: 'checkout' } }
  );
  const ok = check(checkout, { 'checkout 2xx': (r) => r.status >= 200 && r.status < 300 });
  if (ok && checkout.json('errorCode') !== undefined) {
    businessErrors.add(1);
  } else {
    businessErrors.add(0);
  }

  sleep(0.2);
}

Patrones que funcionan

  • Tags en requeststags: { route: 'checkout' } alimenta umbrales filtrados (HTTP metrics).
  • Checks + thresholds — checks validan corrección por iteración; thresholds agregan pass/fail (checks).
  • abortOnFail con delay — para suites largas, aborta tras ventana inicial si error rate explota.
  • Percentiles distintos por criticidad — checkout con p99; catálogo solo p95.

Anti-patrones a evitar

  • Un solo umbral global cuando un script mezcla rutas con SLO de órdenes de magnitud distintos.
  • Umbrales copiados de prod en smoke de CI—demasiado estrictos generan flaky pipelines.
  • Ignorar http_req_failed cuando la red de staging es ruidosa—ajusta tolerancia o segmenta por entorno.

Tip pro (comando de ejemplo):

k6 run mixed-routes.js; echo "exit code: $?"

Qué demuestra este comando: el exit code de k6 refleja violación de umbrales—exactamente lo que CI debe evaluar, no solo logs bonitos.

Marco de decisión: qué umbral para qué pregunta

SituaciónAcción recomendada
Smoke CI post-mergeGlobal p(95) + http_req_failed; duración corta
Ruta crítica (checkout, pago)Umbrales por tag; incluye p(99)
Errores de negocio en HTTP 200Métrica custom Rate + threshold
Suite larga en staging saturadoabortOnFail en error rate tras 30–60 s
Regresión entre releasesMismos umbrales + git SHA archivado (línea base)

Usa umbrales globales si el script golpea una sola ruta homogénea.

Usa filtros por tag si mezclas checkout y catálogo—or any SLO distinto por superficie.

Usa abortOnFail si continuar la corrida no aporta señal—solo consume staging y tiempo.

Observabilidad, documentación y siguientes pasos

Los umbrales solo sirven si el equipo acordó los números. Antes de cablear CI:

  • Documenta SLO fuente (contrato interno, error budget) junto a cada threshold en el script o wiki.
  • Revisa si p95 o p99 es la puerta correcta por ruta (p95 vs p99).
  • Define política para staging flaky—retry vs umbral relajado vs segmentación por entorno.
  • Archiva summary JSON con resultado pass/fail por threshold en cada release.
  • Correlaciona fallos de latencia con telemetría de servidor (análisis de cuellos).

Cómo Performate simplifica umbrales sin copy-paste entre laptops

Umbrales divergentes entre el script de Ana y el de Bob producen CI inconsistente. Abajo hay un ejemplo concreto de flujo para checkout + catálogo con SLO distintos.

Ejemplo: umbrales por ruta en un escenario mixto

  1. Importa requests de catálogo y checkout en un solo escenario de flujo. Problema resuelto: un script, dos superficies—sin duplicar options blocks.
  2. Asigna tags route:catalog y route:checkout en el panel de escenario. Problema resuelto: segmentación alineada al ejemplo k6 sin editar JS.
  3. Define umbrales visuales: catálogo p(95)<250, checkout p(95)<700 y p(99)<1200. Problema resuelto: QA y backend ven los mismos números acordados.
  4. Corre contra staging y revisa pass/fail por threshold en el reporte integrado—not solo gráficos. Problema resuelto: decisiones de merge basadas en criterios, no en vibes.
  5. Compara con corrida anterior en vista de comparación para detectar regresión de cola. Problema resuelto: línea base visible sin spreadsheets manuales.
  6. Exporta script k6 con thresholds para gate en CI (pruebas de carga en CI/CD).

Ese flujo conecta directo con el cta de este post: definir y comparar resultados de umbrales más rápido con escenarios y reportes alineados.

Cierre

El riesgo de release sin umbrales es un problema de criterio, no de tooling. Define pass/fail antes de correr, segmenta rutas críticas por tag, y trata el exit code de k6 como la puerta que CI necesita.

Acordá los números de checkout y catálogo en tu próximo planning—y cablea al menos un threshold de error rate con abortOnFail antes del próximo merge a main.

Try Performate free | Book a demo | k6 thresholds reference

¿Listo para optimizar el rendimiento de tu API?

Define y compara resultados de umbrales más rápido con escenarios y reportes en Performate.

← Volver a todas las entradas