Skip to main content
22 may 2026errores comunes pruebas de carga

Por Performate

10 errores comunes en pruebas de carga (y cómo evitarlos)

Diez fallos recurrentes en pruebas de carga—desde entornos equivocados hasta métricas de vanidad—y cómo los equipos con mentalidad k6 los evitan.

Tu última prueba de carga golpeó staging cinco minutos, promedió 180 ms y todos firmaron—y luego el p99 de checkout en producción se duplicó en una oferta. Esa historia se repite porque los equipos optimizan dashboards verdes en lugar de preguntas honestas: ¿Probamos el entorno correcto? ¿Medimos latencia de cola? ¿Auth, datos y forma del tráfico coinciden con lo que hacen los clientes?

Estos diez errores aparecen en startups y enterprises porque el rendimiento toca producto, datos, infra y política a la vez. En esta guía verás por qué métricas de vanidad y corridas únicas ocultan riesgo, cómo un script k6 codifica guardrails contra los peores fallos, y qué ítems de checklist convierten debates subjetivos en gates de release.

Por qué fallan las pruebas de carga antes del primer request

La mayoría de los fallos son de proceso y medición—no de VUs faltantes. Ancla los arreglos en comportamiento observable: escenarios explícitos, métricas etiquetadas y umbrales alineados con el riesgo de negocio (k6 thresholds, metrics).

  • Fidelidad de entorno incorrecta: bases mini, cachés frías y sidecars ausentes producen gráficos lindos que mienten sobre capacidad (planificación de capacidad).
  • Métricas de vanidad: promedios y picos de VUs impresionan en slides pero ocultan colas infelices (p95 vs p99).
  • Tráfico irreal: tokens estáticos, filas mutables compartidas y cero think time generan fallos que parecen regresiones.
  • Corridas de una sola vez: el rendimiento es una distribución; una muestra un jueves invita a falsa confianza.
  • Confusión de alcance: funcional en verde no prueba contención, agotamiento de pools ni GC bajo carga paralela (contrato vs rendimiento).

Piensa en las pruebas de carga como un simulador de vuelo: si la cabina carece de la mitad de los instrumentos y la pista mide la mitad, aprobar el sim no dice nada del aterrizaje real.

Cuando el dashboard está verde pero producción no

Los equipos suelen descubrir brechas solo tras un incidente: probaron solo /v2, ignoraron tormentas de refresh OAuth o corrieron contra producción sin coordinación. Contrasta tu enfoque con stress vs carga vs spike y un checklist de pruebas de rendimiento de API para que el tipo de escenario coincida con el riesgo que realmente estás reduciendo.

Implementación práctica con k6: guardrails contra los diez errores

El script siguiente codifica arreglos para los errores que nombra este artículo: umbrales en percentiles en lugar de promedios, rutas etiquetadas para diagnóstico, targets vía env (nunca URLs de producción hardcodeadas), think time realista y control por tasa de llegada para que la carga sea honesta cuando el sistema se frena.

Ejemplo de script (ilustrativo—no listo para producción). El fragmento usa URLs, tokens y números SLO ficticios. Adapta base URL, auth, payloads y umbrales a tu entorno.

Qué demuestra este ejemplo:

  • Gates de latencia de cola: umbrales en p(95) y p(99) por ruta—no una línea de promedio que oculta dolor en checkout.
  • Forma de carga honesta: constant-arrival-rate mantiene req/s aunque las respuestas se alenten (evita omisión coordinada de bucles ingenuos).
  • Diagnóstico etiquetado: route:search y route:checkout separan resúmenes para que un endpoint lento no difumine toda la corrida.
  • Seguridad de entorno: API_BASE desde env con default de staging—nunca incrustes URLs de producción en scripts commiteados.
import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';

const BASE = __ENV.API_BASE || 'https://staging.example.com';
const TOKEN = __ENV.TOKEN || 'staging-token-replace-me';

// Error #6: SKUs distintos por iteración, no una fila compartida
const skus = new SharedArray('skus', () =>
  JSON.parse(open('./data/skus.json')).map((s) => s.id)
);

export const options = {
  scenarios: {
    // Error #9: apunta a req/s, no a max VUs de vanidad
    browse: {
      executor: 'constant-arrival-rate',
      rate: Number(__ENV.SEARCH_RPS || 20),
      timeUnit: '1s',
      duration: '8m',
      preAllocatedVUs: 15,
      maxVUs: 60,
      tags: { route: 'search' },
      exec: 'searchFlow',
    },
    checkout: {
      executor: 'constant-arrival-rate',
      rate: Number(__ENV.CHECKOUT_RPS || 5),
      timeUnit: '1s',
      duration: '8m',
      preAllocatedVUs: 10,
      maxVUs: 40,
      tags: { route: 'checkout' },
      exec: 'checkoutFlow',
    },
  },
  thresholds: {
    // Error #3: percentiles, no promedios
    'http_req_duration{route:search}': ['p(95)<400', 'p(99)<700'],
    'http_req_duration{route:checkout}': ['p(95)<800', 'p(99)<1200'],
    http_req_failed: ['rate<0.01'],
    // Error #4: dropped_iterations expone caídas silenciosas de carga
    dropped_iterations: ['count==0'],
  },
};

export function searchFlow() {
  const q = `sku-${__VU}-${__ITER}`;
  const res = http.get(`${BASE}/search?q=${q}`, {
    headers: { Authorization: `Bearer ${TOKEN}` },
    tags: { route: 'search' },
  });
  check(res, { 'search 2xx': (r) => r.status >= 200 && r.status < 300 });
  sleep(Math.random() * 1.5 + 0.5); // Error #8: think time
}

export function checkoutFlow() {
  const sku = skus[(__VU + __ITER) % skus.length];
  const body = JSON.stringify({ sku, qty: 1 });
  const res = http.post(`${BASE}/checkout`, body, {
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${TOKEN}`,
    },
    tags: { route: 'checkout' },
  });
  check(res, { 'checkout 2xx': (r) => r.status >= 200 && r.status < 300 });
  sleep(1);
}

Patrones que funcionan

  • Corre el mismo script dos veces en noches o builds distintos antes de declarar victoria—compara exportaciones de baseline de regresión.
  • Documenta brechas de fidelidad junto a cada gráfico (ratio de tamaño de BD, caché caliente, mesh on/off).
  • Refresca tokens de forma realista cuando OAuth está en el camino (concurrencia OAuth).
  • Revisa scripts generados por IA como código de producción: endpoints, secretos y aserciones antes de escalar (checklist de seguridad con IA).

Anti-patrones a evitar

  • Golpear producción sin ventana escrita, contacto de abort y revisión de radio de impacto.
  • Clonar scripts por microservicio en lugar de etiquetar rutas en un mix honesto.
  • Tratar max VUs como métrica de éxito sin hipótesis ligada a tasa de llegada o concurrencia.
  • Ignorar dropped_iterations cuando el sistema se frena y tu bucle omite trabajo en silencio.

Pro tip (comando de ejemplo): la línea siguiente muestra cómo ver colas de latencia y fallos de umbral en un solo resumen—no es un flag obligatorio en cada corrida.

k6 run guardrails.js --summary-trend-stats="p(95),p(99)" --thresholds-on-summary

Qué demuestra este comando: k6 imprime tendencias de percentiles y resalta qué tags de ruta fallaron qué SLO—para que los revisores debatan umbrales, no capturas de promedios.

Marco de decisión: qué error arreglar primero

SituaciónAcción recomendada
Liderazgo pregunta «¿cuántos usuarios soportamos?»Pasa de presumir max VUs a escenarios por tasa de llegada o modelos abiertos con supuestos documentados
Staging es mucho más chico que prodEtiqueta resultados «solo direccionales»; invierte en volumen de datos prod-like o env de perf dedicado
p99 sube pero la media se ve bienAñade umbrales de percentil por ruta; deja de reportar latencia media en release notes
Fallos se agrupan en un endpointEtiqueta rutas en k6 y APM; arregla el hot path antes de escalar RPS total
Un test de 5 minutos antes de cada releaseExige dos corridas + diff de baseline; añade smoke en CI a baja tasa (CI/CD)

Usa ejecutores por tasa de llegada si necesitas req/s honestos cuando los tiempos de respuesta se estiran—típico en trabajo de SLO de API.

Usa corridas repetidas con scripts congelados si construyes baseline de regresión entre releases o cambios de infra.

Usa defaults estrictos de env y checklists si tu organización alguna vez apuntó un script a producción por accidente—or debatió si «realmente pasó».

Observabilidad, documentación y próximos pasos

Las pruebas de carga confiables sobreviven handoffs a QA, plataforma y finanzas. Antes de escalar tráfico:

  • Documenta brechas de fidelidad de entorno (tamaño de BD, estado de caché, región, mesh) junto a cada resumen exportado.
  • Define umbrales de percentil por ruta crítica—no una sola línea global de http_req_duration.
  • Rastrea dropped_iterations y checks fallidos junto a latencia; caídas silenciosas de carga invalidan claims de throughput.
  • Correlaciona tags de ruta de k6 con APM y logs (correlation IDs) antes de culpar «a la red».
  • Archiva hash del script, archivo env (redactado) y git SHA por corrida para comparar regresiones manzanas con manzanas.

Cómo Performate reduce errores repetitivos de setup

Copiar bloques de ejecutor y reimportar carpetas Postman cada sprint es cómo vuelven los errores #5 y #6. Abajo un ejemplo concreto de flujo para los flujos search + checkout de este artículo.

Ejemplo: de import de colección a corrida con guardrails repetible

  1. Importa una colección Postman con requests search y checkout—o OpenAPI con ambos paths. Problema resuelto: una fuente de verdad en lugar de scripts bifurcados que derivan en dos sprints.
  2. Crea dos escenarios en el editor visualbrowse a 20 req/s y checkout a 5 req/s—reflejando el mix de producción, no conteos de VUs de vanidad. Problema resuelto: forma de tráfico honesta sin editar YAML de ejecutor en cada pasada de tuning.
  3. Aplica tags de ruta (route:search, route:checkout) en el panel de escenario para que los reportes separen latencia igual que el ejemplo k6. Problema resuelto: on-call y QA filtran una exportación, no tres hojas de cálculo.
  4. Define umbrales de percentil en la UI alineados a tu doc SLO—p95/p99 por ruta, tasa de error bajo 1%. Problema resuelto: los debates de release referencian umbrales, no capturas de latencia media.
  5. Corre dos veces antes del sign-off y usa la vista de comparación entre noches o builds. Problema resuelto: la falsa confianza de una sola muestra se vuelve deriva visible.
  6. Exporta el script k6 generado para smoke gates en CI para que tuning local y pipeline queden alineados. Problema resuelto: los mismos guardrails corren en el IDE y en GitHub Actions.

Ese flujo mapea directo al cta de este post: menos errores repetitivos de setup, pruebas más confiables en cada release.

Conclusión

Los errores en pruebas de carga son predecibles—entorno equivocado, métrica equivocada, forma de tráfico equivocada, número de corridas equivocado. Codifica guardrails en un script: umbrales de percentil, tags de ruta, targets vía env y tasas de llegada honestas cuando el sistema se frena.

Corre tu próxima prueba dos veces, etiqueta cada ruta crítica y reporta p99 junto a la media—luego anota cuáles de los diez errores tu equipo aún practica por hábito.

Try Performate free | Reservar demo | Escenarios k6

¿Listo para optimizar el rendimiento de tu API?

Usa flujos Performate para evitar errores repetitivos de setup y correr pruebas más confiables.

← Volver a todas las entradas