El QoS de MQTT (Quality of Service, calidad de servicio) define cuánto se esfuerza el protocolo en entregar un mensaje. Hay tres niveles de QoS —0, 1 y 2— y cada uno añade paquetes de confirmación a cambio de una garantía más fuerte. Elegir el nivel adecuado es una de las decisiones de diseño más importantes en un sistema MQTT: si te quedas corto pierdes datos; si te pasas, desperdicias ancho de banda y añades latencia.
Los niveles de QoS de un vistazo
| QoS | Garantía | Paquetes por salto | ¿Puede haber duplicados? |
|---|---|---|---|
| 0 | Como máximo una vez (at most once) | 1 (PUBLISH) | No, pero los mensajes pueden perderse |
| 1 | Al menos una vez (at least once) | 2 (PUBLISH, PUBACK) | Sí |
| 2 | Exactamente una vez (exactly once) | 4 (PUBLISH, PUBREC, PUBREL, PUBCOMP) | No |
Un detalle importante: el QoS se negocia por salto. El QoS del publicador rige el trayecto hasta el broker, y el QoS de la suscripción rige el trayecto del broker a cada suscriptor.
QoS 0: como máximo una vez
El emisor transmite el PUBLISH una sola vez y se olvida de él. No hay confirmación ni identificador de paquete. Si la conexión TCP se rompe mientras el mensaje está en tránsito, se pierde.
Sender Receiver
| ---- PUBLISH (QoS 0) ---> |
| | (no reply)QoS 0 es la opción más barata y es perfectamente válida para telemetría de alta frecuencia —una lectura de temperatura por segundo, una posición GPS, un heartbeat— en la que el siguiente mensaje sustituye al que se perdió. Ten en cuenta que TCP sigue protegiendo contra la corrupción y el desorden en una conexión activa; el riesgo es perder mensajes cuando se caen las conexiones.
QoS 1: al menos una vez
El emisor asigna un identificador de paquete, guarda el mensaje y espera un PUBACK con el mismo identificador. Hasta que llega la confirmación, el mensaje se considera en vuelo. Si la conexión se cae antes, el emisor lo retransmite con el flag DUP activado cuando se reanuda la sesión.
Sender Receiver
| ---- PUBLISH (QoS 1, id=7) ---> | store + deliver
| <--------- PUBACK (id=7) ------ |
| delete stored message |El inconveniente: si se pierde el PUBACK, el receptor ya ha procesado el mensaje y lo vuelve a recibir en la retransmisión. Por tanto, QoS 1 garantiza la entrega pero permite duplicados. Para la mayoría de las aplicaciones es el equilibrio correcto: haz que tus handlers sean idempotentes (por ejemplo, incluyendo un ID de mensaje o una marca de tiempo en el payload) y obtendrás fiabilidad con poca sobrecarga.
QoS 2: exactamente una vez
QoS 2 usa un handshake de cuatro pasos para que ninguna de las dos partes pueda entregar el mensaje dos veces:
Sender Receiver
| ---- PUBLISH (QoS 2, id=9) ---> | store id=9, (deliver)
| <--------- PUBREC (id=9) ------ |
| ---------- PUBREL (id=9) -----> | release id=9
| <--------- PUBCOMP (id=9) ----- |
| done |PUBLISH: el emisor transmite el mensaje y conserva una copia.PUBREC: el receptor confirma la recepción y registra el identificador de paquete. CualquierPUBLISHretransmitido con ese identificador se reconoce como duplicado y no se vuelve a entregar.PUBREL: el emisor descarta el mensaje e indica al receptor que puede liberar el identificador.PUBCOMP: el receptor lo confirma; el identificador puede reutilizarse.
El coste son dos idas y vueltas por salto y estado en ambos extremos. QoS 2 tiene sentido para mensajes en los que un duplicado es realmente perjudicial y no se puede filtrar en la aplicación: eventos de facturación o comandos de actuador de un solo disparo, por ejemplo. En la práctica, muchos equipos usan QoS 1 con deduplicación en su lugar.
La regla de degradación: el QoS efectivo
Un suscriptor solicita un QoS máximo en su paquete SUBSCRIBE, y el broker devuelve el QoS concedido en el SUBACK. Después, cada mensaje se entrega con el menor entre el QoS de publicación y el QoS concedido a la suscripción:
| Publicado con | Suscrito con | Entregado con |
|---|---|---|
| QoS 2 | QoS 0 | QoS 0 |
| QoS 1 | QoS 2 | QoS 1 |
| QoS 0 | QoS 1 | QoS 0 |
| QoS 2 | QoS 2 | QoS 2 |
Los brokers también pueden limitar el QoS: en MQTT 5 un broker puede anunciar Maximum QoS en el CONNACK, y algunos brokers o servicios cloud no soportan QoS 2 en absoluto. Comprueba siempre el QoS concedido en el SUBACK en lugar de dar por hecho que obtuviste lo que pediste.
QoS y sesiones: qué pasa cuando estás offline
El QoS solo protege los mensajes mientras existe una sesión. Con una sesión limpia (cleanSession=true en 3.1.1, cleanStart=true con un session expiry de 0 en MQTT 5), el broker descarta las suscripciones y los mensajes pendientes en cuanto el cliente se desconecta, así que los mensajes QoS 1 y 2 publicados mientras estás offline simplemente nunca te llegan.
Para recibir los mensajes que llegan mientras un cliente está offline, necesitas estas tres cosas:
- un client ID estable y único,
- una sesión persistente (
cleanSession=falseo, en MQTT 5, unSession Expiry Intervaldistinto de cero), - una suscripción con QoS 1 o 2, y mensajes publicados con QoS 1 o 2.
Ten en cuenta también que la retransmisión de mensajes no confirmados ocurre cuando la sesión se reanuda tras una reconexión: ni 3.1.1 ni 5.0 exigen reenviar en una conexión activa, porque ahí TCP ya se encarga de las pérdidas.
Probar el QoS en la práctica
Puedes ver el QoS en acción con la CLI de Mosquitto. El flag -d imprime cada paquete, así que verás pasar los PUBREC/PUBREL/PUBCOMP:
# subscriber with a persistent session (-c) and fixed client ID
mosquitto_sub -h broker.emqx.io -t 'testmqtt/qos-demo/#' -q 2 -c -i qos-demo-sub -d
# publish at QoS 2
mosquitto_pub -h broker.emqx.io -t 'testmqtt/qos-demo/order' -m 'order-1001' -q 2 -dDetén el suscriptor, publica unos cuantos mensajes QoS 1 y vuelve a arrancarlo con el mismo client ID: deberían llegar los mensajes en cola. En el navegador, el cliente MQTT online te permite elegir el QoS por suscripción y por publicación. Para más escenarios de prueba, consulta cómo probar un broker MQTT.
Pruébalo en el cliente MQTT online
Cómo elegir un nivel de QoS
- QoS 0: datos de sensores frecuentes, posiciones y métricas en las que solo importa el último valor.
- QoS 1: la opción sensata por defecto para eventos, alertas y comandos; combínala con handlers idempotentes.
- QoS 2: casos poco frecuentes en los que los duplicados son costosos y no se pueden deduplicar más adelante.
El QoS funciona de la mano de los mensajes retenidos (retained) y del Last Will; si eres nuevo en el protocolo, empieza por qué es MQTT.
Preguntas frecuentes
¿Qué nivel de QoS de MQTT debo usar?
Usa QoS 0 para telemetría frecuente en la que perder una muestra no importa, QoS 1 para la mayoría de los eventos y comandos (con handlers idempotentes) y QoS 2 solo cuando los duplicados son realmente perjudiciales y no puedes deduplicar en la aplicación.
¿Por qué he recibido dos veces un mensaje QoS 1?
QoS 1 es entrega «al menos una vez». Si se pierde la confirmación, normalmente porque se cayó la conexión, el emisor retransmite el mensaje con el flag DUP activado tras reconectar, así que el receptor puede verlo dos veces.
¿QoS 2 garantiza una entrega exactamente una vez de extremo a extremo?
No. El QoS se aplica a cada salto por separado: del publicador al broker y del broker al suscriptor. El suscriptor recibe el mínimo entre el QoS de publicación y el de su suscripción, y los mensajes para clientes offline solo se conservan si estos tienen una sesión persistente.