Fundamentos de MQTT

Tamaño máximo de mensaje en MQTT: límites y estrategias para payloads grandes

Técnicamente, MQTT puede transportar un paquete de 256 MB, pero los brokers, las librerías cliente y los dispositivos imponen límites muy inferiores. Descubre dónde están los límites reales, qué ocurre cuando los superas y cómo enviar payloads grandes.

Un payload demasiado grande bloqueado en la puerta de un broker para ilustrar el límite de tamaño de mensaje MQTT
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

El límite de tamaño de mensaje MQTT que fija la especificación es de unos 256 MB por paquete, pero el límite que de verdad importa es el que imponen tu broker, tu librería cliente y la memoria de tu dispositivo, que suele ser muy inferior. Esta guía explica cada uno de esos límites, qué ocurre cuando un mensaje es demasiado grande y tres estrategias para mover payloads grandes, como imágenes, registros o firmware, sin romper tus conexiones MQTT.

El techo del protocolo: 256 MB

MQTT codifica la longitud de la cabecera variable y del payload de cada paquete en un campo de "longitud restante" de hasta cuatro bytes, con siete bits útiles cada uno. El valor más grande que cabe es 268.435.455 bytes, aproximadamente 256 MB. Resta el nombre del topic y las cabeceras y tendrás el payload máximo teórico. La codificación se explica byte a byte en la guía de estructura de los paquetes MQTT.

Nadie trabaja en producción cerca de ese techo. Un broker que aceptara mensajes de 256 MB de cualquier cliente sería fácil de agotar: tiene que almacenar el paquete en búfer, posiblemente guardarlo para sesiones offline o como valor retenido, y copiarlo a cada suscriptor. MQTT se diseñó para muchos mensajes pequeños, y todas las capas de un despliegue real lo reflejan.

Dónde están los límites reales

Capa Límite típico Quién lo fija
Especificación MQTT 268.435.455 bytes por paquete Codificación de la longitud restante
Broker Tamaño máximo de mensaje o de paquete configurado Configuración del broker o plan
Negociación de MQTT 5 Propiedad Maximum Packet Size Cliente y broker anuncian cada uno lo que aceptan
Librería cliente Tamaño del búfer interno Valores por defecto de la librería, p. ej. 256 bytes en PubSubClient de Arduino
Dispositivo RAM libre Un microcontrolador puede tener solo decenas de KB disponibles
Red Rendimiento y estabilidad Los mensajes grandes tardan más y fallan con más frecuencia en enlaces débiles

Gana el límite más pequeño de la cadena. Que un broker acepte 1 MB es irrelevante si un suscriptor ESP8266 solo puede almacenar unos pocos kilobytes. Si trabajas con hardware de clase Arduino, la guía del tamaño de búfer de PubSubClient cubre esa trampa en concreto.

Límites de tamaño de mensaje MQTT en ConnectMQ

Estos son los límites actuales por tipo de broker:

Broker Tamaño máximo de mensaje
Broker público de pruebas (broker.connectmq.com) 64 KB
Plan Serverless (Free) 256 KB
Plan Serverless (Paid) 1 MB
Dedicated, BYOC y Self Managed Enterprise Depende del despliegue

Para la mayoría de la telemetría, las alarmas y los comandos, incluso 64 KB es generoso: una lectura de sensor en JSON suele quedar muy por debajo de 1 KB. Si te acercas a estos límites con regularidad, normalmente es señal de que el payload debería ir por otro camino, como se describe más abajo.

Maximum Packet Size en MQTT 5

MQTT 5 hizo explícitos los límites de tamaño con la propiedad Maximum Packet Size (0x27):

  • En CONNECT, el cliente indica al broker el paquete más grande que está dispuesto a recibir. El broker no debe enviar nada mayor; en su lugar, descarta esos mensajes para ese cliente.
  • En CONNACK, el broker indica al cliente el paquete más grande que acepta. Un cliente que envíe más incumple el protocolo.

Ten en cuenta que se trata del tamaño del paquete completo, incluidos la cabecera fija, el topic y las propiedades, no solo del payload. Deja algo de margen.

Leer el límite del broker en MQTT.js:

const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "size-check-8b4d",
  protocolVersion: 5,
  properties: { maximumPacketSize: 64 * 1024 }, // lo que acepta este cliente
});

client.on("connect", (connack) => {
  const max = connack.properties?.maximumPacketSize;
  console.log("Broker maximum packet size:", max ?? "not announced");
  client.end();
});

Si la propiedad no aparece, el broker no anunció un límite en el CONNACK, pero aun así puede imponer uno. Conoce siempre el límite documentado de tu broker.

Qué ocurre cuando un mensaje es demasiado grande

El comportamiento depende de la versión del protocolo y del sentido:

  1. Del cliente al broker, MQTT 5. El broker suele desconectar al cliente con el reason code 0x95 Packet too large.
  2. Del cliente al broker, MQTT 3.1.1. No hay reason code; el broker cierra la conexión. El cliente ve una pérdida de conexión genérica.
  3. Del broker al cliente. Si un suscriptor anunció un Maximum Packet Size menor, el broker descarta el mensaje para ese suscriptor. En 3.1.1, la librería del suscriptor puede fallar al interpretarlo o desconectarse.
  4. Dentro del cliente. Algunas librerías se niegan a enviar y devuelven un error; PubSubClient de Arduino simplemente devuelve false en publish().

El patrón peligroso es un cliente que encola el mensaje demasiado grande, se reconecta y lo reintenta de inmediato. El resultado es un bucle de desconexiones, uno de los motivos clásicos por los que un cliente MQTT se desconecta constantemente. Valida el tamaño antes de publicar y descarta o desvía los mensajes demasiado grandes.

Estrategias para payloads grandes

1. Reduce el payload

Antes de dividir nada, redúcelo. Los nombres de campo en JSON se repiten en cada mensaje; las claves cortas, las codificaciones binarias como CBOR o Protobuf y la compresión gzip suelen reducir los payloads de forma drástica. Enviar solo los valores que cambian en lugar del estado completo también ayuda. La guía del formato de payload MQTT compara las opciones.

2. Trocea el mensaje

Cuando un payload es moderadamente grande, por ejemplo unos cientos de kilobytes de datos de registro, puedes dividirlo en fragmentos numerados y reensamblarlo en el lado receptor. Este publicador en Python divide un archivo en fragmentos de 32 KB con una pequeña cabecera JSON por fragmento:

import base64, hashlib, json, math, time, uuid
import paho.mqtt.client as mqtt

CHUNK = 32 * 1024
TOPIC = "connectmq/demo/8b4d/files"

def send_file(client, path):
    data = open(path, "rb").read()
    transfer_id = uuid.uuid4().hex[:8]
    total = math.ceil(len(data) / CHUNK)
    sha = hashlib.sha256(data).hexdigest()
    for i in range(total):
        part = data[i * CHUNK:(i + 1) * CHUNK]
        msg = {"id": transfer_id, "seq": i, "total": total, "sha256": sha,
               "data": base64.b64encode(part).decode()}
        client.publish(f"{TOPIC}/{transfer_id}", json.dumps(msg), qos=1).wait_for_publish()
        time.sleep(0.15)  # respetar los límites de ritmo por cliente

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="chunker-8b4d")
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
send_file(client, "report.csv")
client.loop_stop()
client.disconnect()

Base64 añade alrededor de un tercio al tamaño, así que 32 KB de datos binarios se convierten en unos 43 KB en la red, holgadamente por debajo del límite de 64 KB del broker público. El suscriptor reúne los fragmentos por id, los ordena por seq y verifica el SHA-256 cuando han llegado las total partes. Usa QoS 1 para que no se pierdan fragmentos en silencio, y prepárate para duplicados y partes que falten con un timeout. En el broker público, ten presente el límite de 10 mensajes por segundo, que es de lo que se encarga la pausa.

El troceado añade complejidad, así que resérvalo para payloads demasiado grandes para un solo mensaje, pero lo bastante pequeños como para que MQTT siga siendo el transporte adecuado.

3. Envía el archivo fuera de banda

Para imágenes, vídeo, imágenes de firmware y exportaciones grandes, el patrón más robusto es mantener los bytes totalmente fuera de MQTT. Sube el archivo a un almacenamiento de objetos o a un servidor web por HTTPS y publica un pequeño mensaje MQTT que apunte a él:

{
  "type": "firmware",
  "version": "2.4.1",
  "url": "https://files.example.com/fw/sensor-2.4.1.bin",
  "sha256": "9f2c...e81a",
  "size": 1048576
}

Los dispositivos descargan el archivo con peticiones HTTP por rangos y soporte de reanudación, verifican el hash e informan del progreso por MQTT. Conservas los puntos fuertes de MQTT, la notificación instantánea y la distribución a muchos dispositivos, mientras HTTP y los servicios de almacenamiento se encargan de la transferencia masiva.

Lista para decidir según el tamaño

  1. Menos de 10 KB: envíalo como un solo mensaje, sin tratamiento especial.
  2. De 10 KB al límite de tu broker: comprime o usa una codificación compacta, y confirma que todos los suscriptores pueden almacenarlo.
  3. Por encima del límite, pero solo de vez en cuando: trocéalo con números de secuencia y sumas de verificación.
  4. Archivos binarios grandes o transferencias masivas periódicas: súbelos fuera de banda y publica una referencia.
  5. En todos los casos: comprueba el tamaño en el código antes de llamar a publish.

Envía mensajes en ConnectMQ

ConnectMQ te ofrece límites claros según el plan, desde mensajes de 256 KB en el plan Serverless gratuito hasta 1 MB en el plan Serverless de pago, con opciones Dedicated, BYOC y Self Managed Enterprise para despliegues más grandes. Experimenta primero en el servidor MQTT público gratuito, pensado para pruebas y no para datos de producción, y pasa a un broker MQTT gestionado cuando necesites credenciales privadas y límites más altos. El tutorial de MQTT cubre los fundamentos si estás empezando.

Empieza con ConnectMQ

Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, y obtén un usuario, una contraseña y un client ID en minutos. Para comparar opciones de alojamiento, lee nuestra guía para elegir un broker MQTT en la nube.

Preguntas frecuentes

¿Cuál es el tamaño máximo de un mensaje MQTT?

El protocolo permite paquetes de hasta 268.435.455 bytes, unos 256 MB. En la práctica, los brokers fijan límites muy inferiores; en ConnectMQ son 64 KB en el broker público, 256 KB en el plan gratuito y 1 MB en el plan Serverless de pago.

¿Qué ocurre si publico un mensaje demasiado grande?

El broker lo rechaza, normalmente cerrando la conexión. Los clientes MQTT 5 reciben el reason code 0x95 Packet too large, mientras que los clientes MQTT 3.1.1 solo ven cómo se cae la conexión.

¿Debo enviar archivos por MQTT?

Los archivos pequeños pueden enviarse directamente o en fragmentos. Para archivos grandes, súbelos por HTTPS a un almacenamiento y publica un pequeño mensaje MQTT con la URL y la suma de verificación.

¿Incluye el límite de tamaño el nombre del topic?

Los límites de los brokers suelen expresarse por mensaje o por paquete, y el Maximum Packet Size de MQTT 5 cuenta el paquete completo, incluidos el topic y las propiedades. Deja margen por encima del tamaño de tu payload.

Artículos relacionados

¿Quién inventó MQTT? La historia, de los oleoductos al IoT

MQTT lo inventaron en 1999 Andy Stanford-Clark, de IBM, y Arlen Nipper, de Arcom, para monitorizar oleoductos vía satélite. Sigue su camino hacia el open source, OASIS, ISO y los brokers MQTT gestionados en la nube de hoy.

8 min de lectura

Por qué tu cliente MQTT se desconecta constantemente (y cómo solucionarlo)

Los bucles de reconexión son uno de los problemas más habituales de MQTT. Conoce las cinco causas típicas, desde los client ID duplicados hasta los timeouts de keep alive y los paquetes demasiado grandes, y sigue un flujo de diagnóstico que localiza la tuya.

9 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.