Pruebas de brokers

Pruebas de carga de un broker MQTT: mide throughput y latencia

Cómo hacer pruebas de carga a un broker MQTT: mide mensajes por segundo, límites de conexiones y latencia p99 con emqtt-bench, mqtt-benchmark y Python.

Actualizado · 9 min de lectura

Pruebas de carga de un broker MQTT: mide throughput y latencia

Un broker que funciona con un cliente de prueba puede caerse con mil dispositivos. Hacer pruebas de carga a un broker MQTT responde tres preguntas antes de que lo haga producción: cuántas conexiones simultáneas acepta, cuántos mensajes por segundo puede enrutar y qué latencia ven tus suscriptores mientras está ocupado.

Esta guía muestra cómo planificar un benchmark, ejecutarlo con dos herramientas open source y un script de Python, y leer los números sin engañarte.

Qué medir

MétricaQué te diceObjetivo típico
Tasa de conexiónLo rápido que el broker acepta nuevos CONNECT (¡tormentas de reconexión!)Cientos por segundo
Conexiones simultáneasLímites de memoria y de descriptores de archivoTamaño de tu flota × 1,5
Throughput de publicaciónMensajes por segundo aceptados de los publicadoresTráfico pico × 2
Throughput de fan-outMensajes por segundo entregados a los suscriptoresDepende del diseño de topics
Latencia de extremo a extremo (p50 / p99)Tiempo desde la publicación hasta la entregap99 por debajo de 50 ms en la región
Tasa de erroresDesconexiones, mensajes QoS 0 perdidos, timeoutsCercana a cero

Haz siempre el benchmark con el mismo QoS, tamaño de payload y estructura de topics que usan tus dispositivos. Una prueba que publica mensajes QoS 0 de 10 bytes en un solo topic no dice nada sobre telemetría QoS 1 de 2 KB repartida en 50.000 topics. Consulta niveles de QoS en MQTT para ver cómo cada nivel cambia el número de paquetes.

Elige el objetivo correcto

Nunca lances un benchmark pesado contra un sandbox público compartido: los números no significan nada (compites con todos los demás usuarios) y los operadores te limitarán o bloquearán. Haz ahí una prueba de humo y luego dirige la carga a una instancia que controles.

En los ejemplos siguientes usamos broker.connectmq.com; sustituye el host, el puerto y las credenciales por los de tu propia instancia.

1. emqtt-bench

emqtt-bench es una herramienta en Erlang capaz de abrir decenas de miles de conexiones desde una sola máquina. La forma más fácil de ejecutarla es con Docker:

Prueba de conexiones — 2.000 clientes a 200/s
docker run --rm -it emqx/emqtt-bench conn \
  -h broker.connectmq.com -p 1883 \
  -c 2000 -R 200 \
  -u "$MQTT_USER" -P "$MQTT_PASS"

Después mide el throughput con un grupo de suscriptores y un grupo de publicadores ejecutándose a la vez:

Terminal 1 — 100 suscriptores
docker run --rm -it emqx/emqtt-bench sub \
  -h broker.connectmq.com -p 1883 \
  -c 100 -t 'bench/%i/#' -q 1
Terminal 2 — 100 publicadores, 1 mensaje cada 10 ms cada uno
docker run --rm -it emqx/emqtt-bench pub \
  -h broker.connectmq.com -p 1883 \
  -c 100 -I 10 -t 'bench/%i/data' -s 256 -q 1

%i se expande al índice del cliente, así que cada publicador tiene su propio topic y su propio suscriptor: un patrón realista de telemetría uno a uno. 100 publicadores × 100 msg/s dan un objetivo de 10.000 mensajes por segundo. emqtt-bench imprime cada segundo las tasas de envío y recepción; si la tasa recibida se queda por detrás de la enviada, el cuello de botella es el broker (o tu red).

2. mqtt-benchmark (Go)

Si prefieres un único binario, mqtt-benchmark publica un número fijo de mensajes e informa de estadísticas de throughput y latencia:

Instalar y ejecutar
go install github.com/krylovsk/mqtt-benchmark@latest

mqtt-benchmark \
  --broker tcp://broker.connectmq.com:1883 \
  --clients 50 --count 1000 --size 512 --qos 1 \
  --topic bench/go --format text

El resumen final incluye los mensajes por segundo por cliente, la tasa agregada y la media / desviación estándar de los tiempos de publicación: una forma rápida de comparar dos brokers o dos configuraciones.

3. Un script de latencia fiable

Las herramientas de throughput miden lo rápido que entran los mensajes. Los usuarios notan lo rápido que salen. Este script de Python (paho-mqtt 2.x) incluye la hora de envío en cada payload y calcula los percentiles de extremo a extremo en el lado del suscriptor:

latency.py
import json, statistics, time, uuid
import paho.mqtt.client as mqtt

HOST, PORT = "broker.connectmq.com", 1883
TOPIC = f"bench/{uuid.uuid4().hex[:8]}/latency"
N, RATE = 2000, 200          # mensajes, mensajes por segundo
samples = []

def on_message(client, userdata, msg):
    sent = json.loads(msg.payload)["t"]
    samples.append((time.perf_counter() - sent) * 1000)

sub = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
sub.on_message = on_message
sub.connect(HOST, PORT)
sub.subscribe(TOPIC, qos=1)
sub.loop_start()

pub = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
pub.connect(HOST, PORT)
pub.loop_start()
time.sleep(1)                # deja que la suscripción se asiente

for i in range(N):
    pub.publish(TOPIC, json.dumps({"i": i, "t": time.perf_counter()}), qos=1)
    time.sleep(1 / RATE)

time.sleep(3)
samples.sort()
p = lambda q: samples[int(len(samples) * q) - 1]
print(f"received {len(samples)}/{N}")
print(f"p50 {p(0.50):.1f} ms  p95 {p(0.95):.1f} ms  p99 {p(0.99):.1f} ms  max {samples[-1]:.1f} ms")
print(f"mean {statistics.mean(samples):.1f} ms")

Como el publicador y el suscriptor se ejecutan en el mismo proceso, comparten un mismo reloj: no hay deriva de NTP en el resultado. Ejecútalo una vez con el broker en reposo y otra mientras emqtt-bench lo está machacando: la diferencia es la latencia que verán tus dispositivos en el pico.

Cómo leer los resultados

  • Recibidos < enviados con QoS 0 significa que el broker o el cliente descartaron mensajes bajo presión. Repite con QoS 1 para ver si es un problema de entrega o de capacidad.
  • p99 muy por encima del p50 apunta a pausas de garbage collection, persistencia en disco o un enlace de red saturado. Revisa la CPU del broker y la del generador de carga: una máquina de benchmark al 100 % es el falso resultado más habitual.
  • La prueba de conexiones se atasca en un número redondo (1.024, 4.096, 65.535): has alcanzado un límite de descriptores de archivo o de puertos efímeros en el generador de carga, no en el broker. Sube ulimit -n o reparte la carga entre varias máquinas o IP de origen.
  • Desconexiones durante la prueba: busca timeouts de keep alive o los límites de inflight / cola por cliente del broker. Consulta keep alive en MQTT y errores de conexión.

Checklist repetible de pruebas de carga

  1. Comprueba primero la conectividad con el cliente MQTT online o con mosquitto_pub / mosquitto_sub.
  2. Fija el escenario: número de clientes, QoS, tamaño de payload, estructura de topics, retained o no.
  3. Sube la carga de forma gradual (10 %, 50 %, 100 %, 150 % del pico esperado) y mantén cada escalón unos minutos.
  4. Registra la CPU, la memoria y el número de conexiones del broker junto a los números del lado del cliente.
  5. Repite la prueba dos veces; confía solo en los resultados que se reproducen.
  6. Vuelve a ejecutarla tras cada actualización o cambio de configuración del broker.

Haz primero una prueba de humo del broker en tu navegador

Las pruebas de carga convierten "funciona en mi portátil" en un número con el que puedes planificar la capacidad. Empieza en pequeño, mide la latencia donde están tus usuarios y guarda los scripts en tu repositorio para que el siguiente benchmark lleve minutos en lugar de días.

Preguntas frecuentes

¿Puedo hacer pruebas de carga contra un broker MQTT público?

Solo de forma ligera. Los sandboxes públicos son compartidos y tienen límites de tasa, y el tráfico intenso degrada el servicio para todos los demás. Haz las pruebas de carga reales contra un broker propio o una instancia privada destinada a pruebas.

¿Qué latencia MQTT es buena?

Dentro de la misma región, un broker sano entrega mensajes QoS 0 de extremo a extremo en pocos milisegundos y QoS 1 en menos de 20 ms con carga moderada. Mide el p99, no la media: los picos son lo que rompe los dispositivos.

¿Qué herramienta es la mejor para benchmarks MQTT?

emqtt-bench es la opción open source más completa para carga de conexiones, publicación y suscripción. mqtt-benchmark (Go) es más fácil de instalar. Un script propio pequeño es lo mejor cuando necesitas tus payloads y tu estructura de topics exactos.