---
title: "Ejemplos de umbrales en k6: alerta sobre las métricas que importan"
description: "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."
publishDate: "2026-05-26"
draft: false
keyword: "ejemplos umbrales k6"
intent: "MOFU"
cta: "Define y compara resultados de umbrales más rápido con escenarios y reportes en Performate."
tags: ["k6", "umbrales", "slo", "rendimiento-api"]
translationOf: k6-thresholds-examples
---

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 cierre** — `p95` 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](https://k6.io/docs/using-k6/metrics/create-custom-metrics/).
- **CI sin dientes** — k6 exit code 0 con umbrales vacíos = pipeline verde que no protege releases.

Lee [p95 vs p99 latencia](/es/blog/p95-vs-p99-latencia) antes de elegir percentiles, y [pruebas de carga en CI/CD](/es/blog/pruebas-de-carga-en-ci-cd) al cablear fallos en pipelines ([thresholds documentation](https://k6.io/docs/using-k6/thresholds/)).

## 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ó.

```javascript
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 requests** — `tags: { route: 'checkout' }` alimenta umbrales filtrados ([HTTP metrics](https://k6.io/docs/using-k6/metrics/)).
- **Checks + thresholds** — checks validan corrección por iteración; thresholds agregan pass/fail ([checks](https://k6.io/docs/using-k6/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):**

```bash
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ón | Acción recomendada |
|:---|:---|
| Smoke CI post-merge | Global `p(95)` + `http_req_failed`; duración corta |
| Ruta crítica (checkout, pago) | Umbrales por tag; incluye `p(99)` |
| Errores de negocio en HTTP 200 | Métrica custom `Rate` + threshold |
| Suite larga en staging saturado | `abortOnFail` en error rate tras 30–60 s |
| Regresión entre releases | Mismos umbrales + git SHA archivado ([línea base](/es/blog/linea-base-regresion-rendimiento-api)) |

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

**Usa filtros por tag si** mezclas checkout y catálogo o cualquier 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](/es/blog/p95-vs-p99-latencia)).
- [ ] 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](/es/blog/analisis-cuellos-de-botella-api)).

## 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—no solo gráficos. *Problema resuelto:* decisiones de merge basadas en criterios, no en intuición.
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](/es/blog/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.

Acuerda 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](https://performate.app) | [Book a demo](/demo) | [k6 thresholds reference](https://k6.io/docs/using-k6/thresholds/)
