API de análisis de resultados

Cada página de resultados de una prueba de carga se construye a partir de un único documento JSON: todas las muestras de la ejecución, agregadas en percentiles, tipos de error y resúmenes por petición, por región y por nivel de usuarios. Ese mismo documento está disponible para tus herramientas a través de la API de análisis, de modo que un panel, un generador de informes o un paso de CI lea exactamente las cifras que muestra la página de resultados.

Endpoint

GET /api/v1/{loadtests|k6tests|jmetertests}/analysis?testrunname=<name>&testrunid=<id>

Envía tu clave de API en la cabecera loadfocus-auth. Usa loadtests para pruebas cloud, k6tests para scripts k6 y jmetertests para planes JMeter. Los dos parámetros son obligatorios; testrunid es el número de ejecución que aparece en la URL de resultados.

curl -H "loadfocus-auth: $LOADFOCUS_API_KEY" \
"https://loadfocus.com/api/v1/loadtests/analysis?testrunname=checkout-flow&testrunid=12"

Una ejecución terminada se calcula una vez y se guarda en caché, así que las llamadas repetidas son baratas. Una ejecución en curso devuelve sus cifras hasta el momento.

Respuestas

EstadoCuerpoSignificado
200el documento de análisisLa ejecución existe y tiene muestras.
404{ "error": "no-data" }Ejecución desconocida, de otro equipo o todavía sin muestras.
503{ "error": "analysis-unavailable" }El cálculo falló o agotó el tiempo. Reintenta; no lo trates como "sin datos" en una puerta de CI.
400{ "error": "testrunname-and-testrunid-required" }Falta un parámetro.

El documento

{
"samples": 50312,
"overall": {
"mean": 212.4, "p50": 180, "p90": 410, "p95": 612, "p99": 1480,
"min": 41, "max": 5120, "sd": 233.1, "latency": 198.7, "connect": 9.2,
"errors": 137, "errorPct": 0.3, "rps": 83.9,
"first": 1756540800000, "last": 1756541400000
},
"labels": [ { "label": "GET /api/products", "samples": 25100, "mean": 190.2, "p50": 160, "p90": 380, "p95": 540, "p99": 1200, "errors": 12, "errorPct": 0.1, "rps": 41.8, "min": 41, "max": 3100, "sd": 201.0, "latency": 180.1, "connect": 8.9 } ],
"byThreads": [ { "vus": 50, "samples": 4210, "mean": 150.3, "max": 900, "errors": 0, "rps": 44.1, "errorPct": 0 } ],
"byRegion": [ { "region": "us-east-1", "samples": 25156, "mean": 170.5, "p95": 480, "p99": 1100, "errors": 40, "errorPct": 0.2, "rps": 41.9 } ],
"errorTypes": [ { "label": "POST /api/checkout", "rc": "502", "count": 90, "message": "Bad Gateway", "messages": 90, "topMessages": [ { "message": "Bad Gateway", "count": 90 } ] } ],
"perSecond": [ { "t": 1756540800000, "samples": 62, "errors": 0, "errorPct": 0 } ],
"histogram": { "step": 50, "buckets": [ { "from": 0, "to": 50, "count": 812 } ], "over": 31 },
"apdex": { "t": 500, "satisfied": 44100, "tolerating": 5200, "frustrated": 1012, "score": 0.93 }
}
  • samples es el número de peticiones registradas en todos los motores y regiones. Todas las demás cifras se calculan a partir de esas muestras, no de medias por motor.
  • overall es la ejecución completa. Los tiempos están en milisegundos; latency es el tiempo hasta el primer byte y connect el tiempo de conexión. rps son las muestras divididas por los segundos activos de la ejecución. first y last son milisegundos epoch.
  • labels tiene una fila por petición (URL o nombre del sampler) con los mismos campos más sus propios percentiles.
  • byThreads agrupa las muestras por el número de usuarios virtuales activos en ese momento. Léelo como tiempo de respuesta frente a carga: el nivel en el que mean o max se dispara es tu capacidad.
  • byRegion es una fila por región cloud, en ejecuciones multirregión.
  • errorTypes es una fila por petición y código de estado fallido, con el mensaje de error más frecuente y hasta cinco topMessages.
  • perSecond es la tasa de error a lo largo del tiempo; las ejecuciones largas se reducen a un máximo de 3.600 puntos.
  • histogram es la distribución de tiempos de respuesta que dibuja la página de resultados, con el número de muestras por encima del último intervalo en over.
  • apdex usa un objetivo de 500 ms: score es (satisfied + tolerating / 2) / total.

Los percentiles salen de 1.000 intervalos logarítmicos, así que p99 es exacto hasta una fracción de porcentaje del valor; no coincidirá al milisegundo con una hoja de cálculo sobre el JTL en bruto.

Condicionar un pipeline

Para una decisión de aprobado o suspenso usa la API de veredicto: aplica los umbrales guardados en la prueba y devuelve un veredicto, que es lo que lee la GitHub Action. Usa la API de análisis cuando necesites las cifras en sí, por ejemplo para publicar el p95 por endpoint en un comentario de pull request o mantener tu propio histórico de tendencias.

Relacionado