Recently I had a discussion about using either XMPP or MQTT within an IoT project. One of the arguments for MQTT was that its a very efficient protocol with very little overhead where XMPP is considered very verbose.
Of course message size is only 1 aspect when choosing a protocol buts for now lets focus on message sizes.
Spoiler
MQTT is clearly the most efficient protocol on the wire. When encryption is taken into account the gap is not so big anymore. Considering all the extra functions you get from XMPP the overhead might be acceptable, depending on your use case.
Protocol | Without encryption | With encryption |
---|---|---|
MQTT | 28 bytes | 68 bytes |
XMPP | 491 bytes | 308 bytes |
XMPP pub/sub uses a transaction to publish a new item. So the publisher first sends a new item to the pubsub service and the pubsub confirms that it received the message. This is the main reason that the total number for publishing gets so large.
I noticed that subsequent XMPP requests take up less space on the wire up to the moment that the transaction takes only 180 bytes for the transaction. I guess this is the compression kicking in.
Using EXI the size of the XMPP messages can be optimised even further but as this is a relatively new XMPP extension proposal this is currently not implemented within XMPP servers (as far as I know).
The test
Lets consider a topic universe/earth
(14 bytes) and a message Hello World! (12 bytes)
and see what this message would take on the wire.
Since MQTT is a pure pub/sub protocol I will compare it with the pub/sub service in XMPP (which might not be the most efficient for your use case).
MQTT
Its pretty easy to determine what the message size in MQTT would be. MQTT adds a 4 bytes header to the topic and the message and the total length on the message would be 28 bytes.
- 2 bytes for the header
- 2 bytes for the topic length
- 26 bytes for the message
If we want to add encryption the message would grow as encryption adds overhead. If the MQTT packet would be encrypted with TLS the overhead per packet is around 40 bytes.
The total message size of an encrypted MQTT message would be 68 bytes.
Note that I did not actually test this on the wire (yes I am lazy)
XMPP
For XMPP its a bit harder to determine the message size as it depends on encryption and compression. Lets consider the following XMPP pub/sub message:
<iq to='pubsub.servicelab.org' type='set' id='123457' xmlns='jabber:client'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='universe/earth' jid='spaceship@servicelab.org'> <item> <entry>Hello World!</entry> </item> </publish> </pubsub> </iq>
Note that this message has information about the identity of the publisher. This information is lost in the MQTT message.
When removing the white space from the message the length would be 252 bytes. But what does it take on the wire?
To test this I’ve used the following:
The server and the client are configured to use TLS and zlib compression. On the wire this message initially will be 202 bytes. When trying to send the again (with another id
) the message size will be a bit smaller: 90 bytes. I guess this is because of the stream compression.
Because XMPP pub/sub uses a request response mechanism for publishing messages to a pub/sub node so the server will send a message back to the client for each message that is published. That message will look like:
<iq type='result' to='pubsub.servicelab.org' from='spaceship@servicelab.org' id='123456'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='universe/earth'> <item id='ae890ac52d0df67ed7cfdf51b644e901'/> </publish> </pubsub> </iq>
This message is 239 bytes large. On the wire it will take 138 bytes. Subsequent message with another id
and item id
will be around 106 bytes in size.
The total message size on the wire is initially 308 bytes for a new connection but sizes may very when a connection is kept alive longer. The total size of the XML is 491 bytes.
Comparing other functions
Above I’ve focused on comparing message sizes but what about other functions? Message size isn’t the only thing to look at when choosing a protocol. XMPP offers a lot of features that MQTT does not offer like identity, federation and all kind a extensions also specific for the IoT.
MQTT is really nice as a messaging bus in a single domain where devices belong to a single entity. I find the strength of XMPP is in the fact that it federates which make it more suitable in a multi domain, multi entities (or business roles) environment.
You make bias when applying compression to XMPP encryption, then do not do the same to MQTT one.
Fair point, but I would not expect that MQTT messages would be compressed at the same rate you get with XMPP. In MQTT there is not a lot to compress but the payload. In XMPP the protocol itself can be compressed pretty well.
Actually, TLS does the compresses in both XMPP and MQTT. But the TLS overhead cancels out the effects of the compression in the MQTT case. Of course this depends on the payload of the message. The point is the XMPP profits much more from the TLS encryption than MQTT would, effectively making the difference in bytes on the wire much smaller.