Un sistema puede funcionar perfectamente en tu portátil con un único usuario y, sin embargo, derrumbarse el día del lanzamiento cuando llegan miles de personas a la vez. El rendimiento no se adivina: se mide. Y la única forma de saber cómo se comportará un sistema bajo carga real antes de que ocurra es someterlo a pruebas de carga controladas. En esta lección aprenderás a distinguir y medir correctamente las dos magnitudes fundamentales del rendimiento (latencia y throughput), por qué los promedios mienten y debes usar percentiles (p95, p99), los distintos tipos de prueba según lo que quieras descubrir (carga, estrés, soak, spike), cómo escribir una prueba real con k6 y JMeter, y cómo localizar los cuellos de botella que limitan tu sistema.

Contenido

  1. Latencia vs Throughput
  2. Por qué los promedios mienten: percentiles p95/p99
  3. Tipos de prueba de rendimiento
  4. Ejemplo práctico con k6 y JMeter
  5. Identificación de cuellos de botella
  6. Errores comunes y consejos
  7. Ejercicios

  1. Latencia vs Throughput

Son las dos métricas básicas del rendimiento y conviene no confundirlas:

  • Latencia: el tiempo que tarda una petición en completarse. Se mide en milisegundos. Responde a "¿cómo de rápido?".
  • Throughput (rendimiento/caudal): el número de peticiones que el sistema procesa por unidad de tiempo. Se mide en peticiones por segundo (req/s). Responde a "¿cuántas a la vez?".
Latencia Throughput
Mide Tiempo de una petición Peticiones por segundo
Unidad ms (milisegundos) req/s (peticiones/seg)
Pregunta ¿Cómo de rápido responde? ¿Cuánto volumen aguanta?
Lo nota El usuario individual El sistema en conjunto

La analogía de la autopista lo aclara: la latencia es lo que tarda un coche en recorrerla; el throughput es cuántos coches pasan por minuto. Y son independientes: una autopista puede tener mucho throughput (muchos carriles) pero alta latencia (es muy larga). De hecho, cuando un sistema se satura, el throughput se estanca mientras la latencia se dispara, porque las peticiones empiezan a hacer cola.

  1. Por qué los promedios mienten: percentiles p95/p99

Imagina que mides la latencia y obtienes una media de 100 ms. Suena bien... pero la media oculta los casos malos. Si de cada 100 peticiones, 95 tardan 50 ms y 5 tardan 1.500 ms, la media sigue siendo baja, pero 1 de cada 20 usuarios sufre una experiencia pésima.

La solución son los percentiles:

Percentil Significado
p50 (mediana) La mitad de las peticiones tardan menos que esto
p95 El 95% tarda menos; el 5% peor queda fuera
p99 El 99% tarda menos; refleja el 1% peor
p99,9 Para servicios muy exigentes; la "cola larga"
Latencias de 20 peticiones (ms), ordenadas:
  40 42 45 48 50 50 52 55 58 60 62 65 70 75 80 90 110 250 800 1500

  Media (promedio):  ~135 ms   <- engañosa, la "infla" un único valor de 1500
  p50 (mediana):       ~61 ms   <- la experiencia típica
  p95:                 ~800 ms   <- 1 de cada 20 sufre esto
  p99:                ~1500 ms   <- el peor caso real

La regla profesional: define tus objetivos (SLO) en percentiles, no en medias. Un buen objetivo es del tipo "el p95 debe estar por debajo de 300 ms". Los percentiles altos (p99, p99,9) importan especialmente porque en sistemas con muchas dependencias, una petición de usuario activa muchas internas, y basta con que una caiga en la cola lenta para arruinar la experiencia.

  1. Tipos de prueba de rendimiento

No todas las pruebas buscan lo mismo. Según la forma de aplicar la carga, distinguimos:

Tipo Qué hace Qué descubre
Carga (load) Carga esperada sostenida ¿Cumplo mis SLO en condiciones normales?
Estrés (stress) Subir la carga hasta romper ¿Cuál es mi límite? ¿Cómo falla?
Soak (resistencia) Carga moderada durante horas/días ¿Hay fugas de memoria o degradación lenta?
Spike (pico) Subida brusca y repentina ¿Aguanta un pico súbito (oferta flash, viral)?
graph LR
    L["Load: carga estable"]
    S["Stress: sube hasta romper"]
    K["Soak: estable, muchas horas"]
    P["Spike: pico repentino"]

Cada tipo responde a un riesgo distinto del negocio:

  • La prueba de carga valida que el sistema cumple los SLO con el tráfico previsto.
  • La de estrés revela el punto de ruptura y, crucialmente, cómo se rompe (¿degrada con elegancia o colapsa?).
  • La de soak detecta problemas que solo aparecen con el tiempo: fugas de memoria, conexiones que no se cierran, discos que se llenan de logs.
  • La de spike simula eventos como una campaña viral o una venta flash, comprobando si el autoescalado reacciona a tiempo.

  1. Ejemplo práctico con k6 y JMeter

k6 es una herramienta moderna de pruebas de carga en la que los escenarios se escriben como código JavaScript, ideal para integrarla en CI/CD.

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

// Definimos el perfil de carga: subimos, mantenemos y bajamos usuarios virtuales
export const options = {
  stages: [
    { duration: '30s', target: 50 },   // Sube de 0 a 50 usuarios en 30s
    { duration: '1m',  target: 50 },   // Mantiene 50 usuarios durante 1 minuto
    { duration: '20s', target: 0 },    // Baja a 0 (rampa de bajada)
  ],
  thresholds: {
    http_req_duration: ['p(95)<300'],  // CRITERIO: el p95 debe ser < 300 ms
    http_req_failed:   ['rate<0.01'],  // y menos del 1% de errores
  },
};

export default function () {
  const res = http.get('https://api.miempresa.com/productos');
  check(res, { 'status 200': (r) => r.status === 200 });  // Verifica respuesta OK
  sleep(1);   // Pausa de 1s simulando el "tiempo de lectura" del usuario
}

Explicación detallada: el bloque stages define un perfil de carga en tres fases (rampa de subida, meseta y bajada), donde target son los usuarios virtuales (VU) simultáneos. Los thresholds son el corazón de la prueba: son los criterios de aprobado/suspenso; si el p95 supera 300 ms o los errores pasan del 1%, k6 marca la prueba como fallida (muy útil para que un pipeline de CI/CD bloquee un despliegue lento). La función default es lo que ejecuta cada usuario virtual en bucle: pide la lista de productos, verifica con check que devuelve 200, y hace una pausa de 1 segundo simulando comportamiento humano.

# Ejecutar la prueba de carga con k6
k6 run prueba-carga.js

JMeter, de Apache, es la herramienta clásica, basada en interfaz gráfica y planes de prueba en XML. Es muy potente y madura, con soporte para muchos protocolos. Comparativa rápida:

k6 JMeter
Definición de la prueba Código (JavaScript) GUI / XML
Curva de aprendizaje Suave para desarrolladores Más pronunciada
Integración CI/CD Excelente (nativa) Posible, más laboriosa
Consumo de recursos Bajo y eficiente Mayor (basado en JVM/hilos)
Protocolos Sobre todo HTTP/web Muchos (JDBC, FTP, JMS...)

La elección depende del contexto: k6 brilla en equipos de desarrollo y automatización; JMeter en escenarios complejos y multiprotocolo o cuando se prefiere una herramienta visual.

  1. Identificación de cuellos de botella

Un cuello de botella (bottleneck) es el recurso que limita el rendimiento de todo el sistema: por mucho que mejores el resto, el sistema no irá más rápido que su componente más lento. La metodología consiste en aplicar carga y observar qué recurso se satura primero.

Sospechosos habituales, en orden de frecuencia:

Cuello de botella Síntoma típico Posible solución
Base de datos CPU de la BD al 100%, consultas lentas Índices, caché, réplicas de lectura
Pool de conexiones Peticiones esperando conexión libre Aumentar el pool, liberar conexiones antes
CPU de la aplicación CPU al 100% con poco tráfico Optimizar código, escalar horizontalmente
Memoria Garbage collection frecuente, swapping Más RAM, corregir fugas de memoria
Red / E/S Latencia alta sin saturar CPU Comprimir, reducir llamadas, CDN
Bloqueos / contención Throughput no sube al añadir usuarios Reducir secciones críticas (recuerda la USL)

El proceso correcto es iterativo: encuentras el cuello de botella, lo resuelves, vuelves a medir... y aparece otro cuello de botella distinto (porque ahora el límite está en otra parte). Optimizar es ir destapando límites sucesivos. Y una advertencia esencial: no optimices sin medir antes. La intuición sobre dónde está el problema suele equivocarse; los datos de una prueba de carga, no.

Errores Comunes y Consejos

  • Fijarse solo en la media. Oculta los casos malos. Mide siempre p95 y p99.
  • Confundir latencia con throughput. Son cosas distintas; un sistema rápido por unidad puede tener poco caudal y viceversa.
  • Probar contra un entorno distinto de producción. Si el entorno de pruebas tiene la mitad de recursos o datos de juguete, los resultados no son extrapolables. Usa un entorno realista.
  • No incluir tiempos de espera realistas. Usuarios que machacan sin pausa (sleep) generan una carga irreal. Modela el comportamiento humano.
  • Optimizar a ciegas. Adivinar el cuello de botella desperdicia esfuerzo. Mide, identifica y solo entonces actúa.
  • Olvidar las pruebas soak. Muchos fallos (fugas de memoria) solo aparecen tras horas. No basta con pruebas cortas.
  • Consejo: integra una prueba de carga en tu CI/CD con thresholds en percentiles, para que el rendimiento sea un criterio de calidad automático y no una sorpresa en producción.

Ejercicios

  1. Interpretar percentiles. Un servicio tiene latencia media de 80 ms, p50 de 70 ms, p95 de 600 ms y p99 de 2.000 ms. ¿Está sano? ¿Qué te preocupa y qué investigarías?

  2. Elegir el tipo de prueba. Para cada objetivo, indica el tipo de prueba: (a) saber a partir de cuántos usuarios el sistema deja de cumplir el SLO; (b) comprobar si hay una fuga de memoria que tumba el servicio tras 12 horas; (c) validar que el sistema sobrevive al pico de tráfico del lanzamiento de un producto.

  3. Definir thresholds. El negocio exige que "el 99% de las peticiones respondan en menos de medio segundo y que fallen menos del 0,5%". Escribe el bloque thresholds de k6 correspondiente.

Soluciones

  1. No está sano, pese a la buena media y mediana. El p50 de 70 ms indica que la experiencia típica es buena, pero el p95 de 600 ms y, sobre todo, el p99 de 2.000 ms revelan una "cola larga": el 5% de los usuarios sufre lentitud y el 1% espera 2 segundos. Investigaría qué tienen en común esas peticiones lentas: ¿consultas a la base de datos sin índice?, ¿pausas de garbage collection?, ¿llamadas a un servicio externo lento? Las trazas distribuidas (lección anterior) son la herramienta ideal para localizarlo.

  2. (a) Prueba de estrés (subir la carga hasta encontrar el punto donde se incumple el SLO/se rompe). (b) Prueba de soak/resistencia (carga sostenida durante muchas horas para detectar degradación lenta). (c) Prueba de spike/pico (subida brusca y repentina de tráfico).

  3. Bloque de thresholds:

    thresholds: {
      http_req_duration: ['p(99)<500'],   // p99 por debajo de 500 ms
      http_req_failed:   ['rate<0.005'],  // menos del 0,5% de errores
    }
    

Conclusión

Has aprendido que el rendimiento se mide, no se supone: que la latencia (tiempo por petición) y el throughput (volumen por segundo) son magnitudes distintas, que los percentiles p95/p99 cuentan la verdad que la media oculta, que cada tipo de prueba (carga, estrés, soak, spike) responde a un riesgo distinto, cómo escribir pruebas reales con k6 y JMeter, y cómo localizar cuellos de botella de forma iterativa y basada en datos. Validar el rendimiento antes de producción es la diferencia entre un lanzamiento exitoso y un colapso público.

Con esta lección cierras el Módulo 9, Calidad, Seguridad y Observabilidad. Has recorrido la escalabilidad, la alta disponibilidad, la seguridad por diseño, la observabilidad y el rendimiento: los cinco atributos que separan una aplicación que "funciona en mi máquina" de un sistema robusto, seguro y preparado para el mundo real. Estos conceptos no son fases finales, sino criterios que deben guiar cada decisión de arquitectura desde el primer día.

Curso de Arquitectura de Aplicaciones

Módulo 1: Fundamentos de la Arquitectura de Aplicaciones

Módulo 2: Principios y Tácticas de Diseño

Módulo 3: Estilos y Patrones Arquitectónicos

Módulo 4: Arquitecturas Distribuidas y Microservicios

Módulo 5: Arquitecturas Dirigidas por Eventos y Mensajería

Módulo 6: Diseño Dirigido por el Dominio (DDD)

Módulo 7: Datos y Persistencia

Módulo 8: Arquitectura en la Nube y Despliegue

Módulo 9: Calidad, Seguridad y Observabilidad

Módulo 10: Evolución, Gobernanza y Casos Prácticos

© Copyright 2026. Todos los derechos reservados