Guías

Pruebas de carga gRPC: herramientas, configuración, métricas

7 min de lectura

Una prueba de carga gRPC necesita una herramienta que hable HTTP/2 y Protocol Buffers: k6 y ghz lo hacen de serie, JMeter necesita un plugin, el soporte gRPC de Gatling está limitado en su edición gratuita y en Locust tienes que integrar tú mismo un cliente gRPC. Cuenta los resultados por estado gRPC, no por estado HTTP, porque las llamadas fallidas siguen llegando como HTTP 200, y comprueba que la carga llega a todos los backends.

Para este artículo no se ejecutó ninguna prueba gRPC. Los datos sobre herramientas salen de la documentación y los repositorios de cada proyecto, comprobados el 16 de octubre de 2026; los datos sobre LoadFocus salen de su código.

HerramientaSoporte gRPCLee la API desdeControl del ritmo
k6Integrado (k6/net/grpc), llamadas unarias y streamsArchivos .proto o reflexión del servidorEjecutores arrival-rate
ghzHerramienta de línea de comandos dedicada a gRPC.proto, protoset o reflexión del servidor--rps y planes de carga
JMeterPlugin de terceros (jmeter-grpc-request)Una carpeta de archivos .protoThread Groups y temporizadores
GatlingComponente gRPC aparte; edición gratuita limitada a 5 usuarios, 5 minutosCódigo generado desde los .proto con protocPerfiles de inyección
LocustSin cliente integrado; envuelve uno y reporta las llamadasTu cliente gRPC de PythonTiempos de espera, constant_throughput

¿Por qué gRPC necesita una prueba de carga distinta de REST?

gRPC va sobre HTTP/2, envía Protocol Buffers binarios en lugar de JSON, pone el resultado de la llamada en un trailer en vez de en el estado HTTP y multiplexa muchas llamadas sobre una sola conexión. Cada una de esas cosas cambia cómo escribes la prueba o lees sus resultados.

El artículo sobre balanceo de carga en gRPC enumera las características de HTTP/2 que importan aquí: un protocolo binario, muchas peticiones multiplexadas en una conexión y compresión de cabeceras, con mensajes Protobuf fuertemente tipados encima (comprobado el 16 de octubre de 2026). Una herramienta que solo envía JSON sobre HTTP/1.1 no puede llamar a un método gRPC, así que comprueba primero el soporte del protocolo.

¿Qué herramienta deberías usar?

Usa k6 si quieres escenarios, checks y umbrales escritos en código; usa ghz para un benchmark rápido de un método desde la línea de comandos. Recurre a JMeter, Gatling o Locust cuando tu equipo ya hace todo lo demás con ellos.

  • k6. El módulo k6/net/grpc carga definiciones Protobuf, se conecta, hace llamadas unarias con invoke y abre streams. Reporta grpc_req_duration y el número de mensajes de los streams en sus métricas.
  • ghz. Una herramienta de benchmark de línea de comandos solo para gRPC. Sus opciones incluyen --rps, --concurrency, --total y --duration, y si no pasas ni --proto ni --protoset intenta la reflexión del servidor. La última versión es v0.121.0 (comprobado el 16 de octubre de 2026).
  • JMeter. El núcleo de JMeter no tiene sampler gRPC; el plugin jmeter-grpc-request añade uno que lee una carpeta de archivos .proto, sin generar código (última etiqueta v1.2.6, comprobado el 16 de octubre de 2026).
  • Gatling. El README de Gatling pone gRPC, MQTT y GraphQL bajo la Gatling Enterprise Component License, limitados en Community Edition a 5 usuarios simultáneos y pruebas de 5 minutos (comprobado el 16 de octubre de 2026). Su guía de configuración de gRPC genera código a partir de tus archivos .proto con protoc.
  • Locust. Su documentación sobre probar otros sistemas incluye un ejemplo de gRPC: envuelves un cliente gRPC para que cada llamada se reporte a Locust, y constant_throughput limita una tarea a un número máximo de ejecuciones por segundo.

Elige ghz en lugar de k6 cuando solo necesitas saber cómo se comporta un método a un ritmo dado y no quieres escribir un script. Elige Locust en su lugar cuando tu equipo escribe en Python y la prueba necesita lógica que resulta más fácil ahí.

¿Cómo se escribe una prueba de carga gRPC en k6?

Carga el archivo .proto en el código de inicialización y, en cada iteración, conéctate, llama al método y comprueba el estado gRPC. La estructura sigue el ejemplo de la documentación de k6.

import grpc from 'k6/net/grpc';
import { check } from 'k6';

const client = new grpc.Client();
client.load(['protos'], 'hello.proto');

export const options = { vus: 20, duration: '1m' };

export default () => {
  client.connect('grpc.example.com:443');
  const res = client.invoke('hello.Greeter/SayHello', {
    name: 'load test',
  });
  check(res, {
    'status is OK': (r) => r && r.status === grpc.StatusOK,
  });
  client.close();
};

La página de invoke usa la misma secuencia de carga, conexión, llamada, comprobación y cierre. connect usa TLS salvo que pases plaintext: true, y con reflect: true pide su API al servidor en lugar de leer un archivo .proto (parámetros de conexión). Para mantener un ritmo de peticiones en vez de un número de usuarios, ejecuta la función en un escenario arrival-rate.

¿Cómo se hace un benchmark rápido con ghz?

Indica a ghz el método, un cuerpo de petición y un ritmo o una concurrencia, y muestra un histograma de latencia, percentiles y un recuento por código de estado. Sirve para un primer vistazo a un método.

ghz --insecure --proto ./hello.proto \
  --call hello.Greeter.SayHello \
  -d '{"name":"load test"}' \
  --rps 200 -c 50 -z 1m \
  localhost:50051

--rps fija el ritmo objetivo, repartido entre los workers, -c cuántos workers hay y -z la duración. Quita --proto para que ghz use la reflexión del servidor, si el servidor la tiene activada. La página de salida de ghz muestra un informe de ejemplo.

¿Qué deberías medir en una prueba de carga gRPC?

Mide los percentiles de latencia de las llamadas, el rendimiento y el número de cada código de estado gRPC. Una tasa de éxito a nivel HTTP puede marcar 100 % mientras las llamadas fallan, porque el resultado viaja en el trailer grpc-status.

La especificación de gRPC sobre HTTP/2 fija el estado HTTP en :status 200 y lleva el resultado de la llamada en trailers como grpc-status y grpc-message. La lista de códigos de estado tiene los que más importan bajo carga:

  • DEADLINE_EXCEEDED (4): el plazo venció antes de que terminara la llamada.
  • RESOURCE_EXHAUSTED (8): se agotó una cuota o un recurso.
  • INTERNAL (13): se rompió un invariante interno, un código reservado para errores graves.
  • UNAVAILABLE (14): suele ser pasajero; reintentar con backoff puede resolverlo, aunque no siempre es seguro en llamadas no idempotentes.

Cuenta cada uno por escalón de carga. Los errores de plazo pueden subir mientras las llamadas que tienen éxito aún parecen rápidas, porque las lentas se cortan en el plazo en lugar de registrarse como lentas. Nuestra guía de criterios de aprobación en pruebas de carga muestra cómo convertir esos recuentos en umbrales.

¿Por qué toda la carga cae en un solo servidor?

Porque gRPC multiplexa muchas llamadas sobre una conexión de larga duración, un balanceador que trabaja por conexión envía cada llamada de esa conexión al mismo backend. Un generador de carga con pocas conexiones puede entonces saturar un servidor mientras los demás están parados.

El artículo sobre balanceo de carga en gRPC explica el mecanismo. Un balanceador a nivel de transporte (L3/L4) termina la conexión TCP y abre otra hacia un backend elegido, copiando las tramas HTTP/2 y gRPC entre ambas; un balanceador a nivel de aplicación (L7) analiza HTTP/2 y puede repartir los streams de una misma conexión de cliente entre varios backends. Si tus clientes de producción pasan por un balanceador L7 o balancean del lado del cliente, prueba por el mismo camino y revisa la CPU y el número de peticiones de cada backend durante la ejecución.

¿Se pueden ejecutar pruebas de carga gRPC en LoadFocus?

No de forma que sus informes lo muestren. LoadFocus ejecuta la versión estándar de k6 v0.57.0, que incluye el módulo gRPC, pero su agente de k6 solo envía a los resultados las muestras de peticiones HTTP, así que las llamadas gRPC generarían carga sin aparecer en sus gráficos ni en sus recuentos de errores.

Hay dos límites más. La subida de archivos de k6 acepta archivos .js, .ts, .csv, .txt, .json, .env y .properties, no archivos .proto, así que un script tendría que conectarse con reflect: true. Y la vía de JMeter está cerrada: los agentes de JMeter de LoadFocus traen JMeter 5.6.2 con plugins preinstalados que no incluyen un sampler gRPC, y la subida de JMeter no acepta archivos JAR de plugins. Para gRPC, ejecuta k6 o ghz en tus propias máquinas y usa los scripts de k6 en LoadFocus para la parte HTTP del mismo sistema, donde genera carga desde 25 regiones.

FAQ

¿Se pueden hacer pruebas de carga de llamadas gRPC en streaming? Sí, con k6 y ghz. El módulo gRPC de k6 tiene una clase Stream con write, end y manejadores de eventos, y ghz tiene opciones para intervalos y duraciones de streaming. Mide los mensajes enviados y recibidos además de la latencia de las llamadas.

¿Hace falta el archivo .proto para hacer una prueba de carga de un servicio gRPC? No si el servidor tiene la reflexión activada. k6 puede conectarse con reflect: true, y ghz recurre a la reflexión cuando no pasas ni --proto ni --protoset. Sin reflexión necesitas el archivo .proto o un protoset compilado.

¿Por qué mis errores gRPC no aparecen como peticiones fallidas? Porque el estado HTTP de una llamada gRPC es 200 aunque la llamada falle. El resultado está en el trailer grpc-status, así que comprueba ese valor en tu script y cuenta cada código por separado.

Lecturas relacionadas


Las afirmaciones técnicas de este artículo no se han revisado de forma independiente.

LoadFocus team
Escrito por el equipo de LoadFocus, las personas detrás de un servicio de pruebas de carga en la nube.