MQTT vs Websockets vs HTTP/2: The Best IoT Messaging Protocol?



While doing any sort of development for an Internet of Things (IoT) connected device such as an Arduino, Raspberry Pi, or other embedded platform, the question inevitably comes up as to what is the best messaging protocol to use? Assuming your application can’t use straight up web pages, there are really two viable options at the moment and one up-coming.

MQTT

MQ Telemetry Transport (MQTT) from IBM is the bad boy of small device messaging. It uses TCP, is lightweight, and has features beneficial to IoT devices. It is mature and there are a lot of client and server implementations, making it easier to develop upon.

MQTT works on a pub/sub architecture. A client subscribes to a channel on a server, and when a server receives new information for that channel, it pushes it out to that device.

Another great feature of MQTT is that you can set a priority or Quality of Service (QoS):

  • 0: The client/server will deliver the message once, with no confirmation required.
  • 1: The client/server will deliver the message at least once, confirmation required.
  • 2: The client/server will deliver the message exactly once by using a handshake process.

Each level uses more bandwidth but will give you varying assurance of deliverability.

With MQTT your application must have a library to talk to the MQTT server and handle publish/subscribe methods.

Websockets

Now that browser websockets are standardized, they make a very compelling option for reading and writing data to IoT devices. Websockets are the best way to achieve full push/pull communications to a web server, which is not possible over basic HTTP protocol.

Websockets are great if you have a full web client! However, with many IoT devices, it is a lot of overhead which might not even be an option.

Another downside of using Websockets is that you would need to come up with your own protocol for the transmission of data. This isn’t too difficult (for example, using JSON) but does create a non-standard protocol.

MQTT over Websockets

A frequent use of Websockets is to actually use MQTT over Websockets. With this configuration, you can use the Paho JS MQTT client to make the connections and to read/write data. This makes for very easy development, but again you must be able to run the full browser stack on the device, so this can be very limiting. Since it does use MQTT, it may be beneficial to use this for any webpage MQTT reading of data. There is also some configuration to be done in the background to create the proxy between MQTT and Websocket, however there are plenty of services such as HiveMQ to do this for you.

HTTP/2

The new HTTP protocol, soon to be seen everywhere, usually a totally different structure than HTTP/1.1. Where HTTP/1 was based on frames/packets, HTTP/2 is a streaming protocol. It supports a few features useful in this situation such as the ability for the client to suspend data streaming, however also has some drawbacks. HTTP/2 was designed to have the client remain connected to the server for the remainder of the browsing session. If using HTTP/2 as a messaging protocol, it would mean leaving this connection open indefinitely. You also miss out on some of the features of MQTT such as QoS. HTTP/2 is so new that some of these features could in theory be added to the protocol and libraries, however it is not yet mature enough to say whether that will happen.

For more discussion on this, check out Can HTTP/2 Replace MQTT from @kellogh.

What’s the Best?

Right now for most applications, I would say MQTT is the best protocol to use for most IoT devices. Since it is so widely adopted, even newer solutions like Websockets support MQTT in some respects so your device will be able to communicate its data effectively to other devices over the internet.

I’m excited to see where HTTP/2 takes us with regards to the Internet of Things. The protocol is better suited for lightweight communication and could definitely be a contender in the future.

Photo courtesy NodeMCU Wikipedia

  • CoAP

    use CoAP! ;)