HiveMQ - TLS and MQTT: How is the performance affected?
Written by The HiveMQ Team
Category: MQTT Iot Security
Published: March 21, 2016
TLS and MQTT
When using any communication technology over the Internet or any other untrusted communication channel without any security measures, it’s easy for attackers to read and manipulate data. This is also true for MQTT. So it’s paramount to use secure communication for IoT use cases, especially when sending data over the Internet.
Under normal circumstances MQTT is used together with TCP, so all standard mechanisms to protect the communication - SSL/TLS in particular - can be used with MQTT. For an in-depth introduction to TLS and MQTT, take a look at the MQTT Security Fundamentals Chapter on TLS.
Secure communication with TLS comes with a price, though. The main tradeoff with TLS is, that resource consumption is significantly higher compared to plain TCP. This post strives to give an overview how significant additional resource consumption is when using TLS.
To jump right into the nitty-gritty technical details, you can download the benchmark document for TLS here: TLS Benchmark Document
A client initiates a secure communication session by starting the TLS Handshake. Client and server then agree on the TLS version and the Cipher Suites for securing the channel. This process is very costly in terms of CPU and bandwidth.
The good news is, that a MQTT client only needs to establish a connection once per session - in contrary to protocols like HTTP, which needs to re-establish a connection on every request (if no keep-alive is used or other techniques like Long Polling are in place). Once connected to the broker, the client can send and receive messages without any additional handshake overhead. The use of TLS needs to allocate additional buffers, so RAM consumption is also slightly higher per MQTT connection.
TLS also has additional overhead for each MQTT message sent. Depending on the cipher suite used for the connection, the TLS overhead at runtime varies. Block Ciphers typically cause more overhead compared to Stream Ciphers in terms of traffic (due to Padding). The runtime overhead in terms of CPU is also higher compared to standard TCP, since cryptographic operations are involved.
The exact overhead of TLS depends on various factors. We conducted a benchmark on Amazon Webservices EC2 to measure the actual resource consumption when enabling secure communication.
We don’t like artificial benchmarks which do not represent real-world scenarios, so we tested with parameters that we would actually use in production systems. We even took it a step further and used 4096-bit X509 server certificates, which has massive computation overhead compared to 1024-bit or 2048-bit certificates. The good news is, that when using certificates with lower bitrates, your results will even get better for the TLS handshake.
We used 50.000 real MQTT clients which sent messages to 50.000 MQTT topics with QoS 1. Each client sent (and received) a message every 10 seconds. So 5.000 incoming publishes and 5.000 outgoing publishes were sent and received each second.
The benchmark had the following parameters:
|TLS Version 1.2||Cipher Suite|
|TLS_RSA_WITH_AES_128_CBC_SHA||Total MQTT clients|
|Total MQTT messages / second||10.000 (5.000 in and 5.000 out)|
|New Connections per second||100|
The following chart shows comparison of CPU usage for plain TCP vs TLS:
You can find the whole benchmark here: Download Benchmark Document
TLS affects performance significantly, especially CPU usage during the handshake. Once MQTT clients are connected, the overhead is negligible. We used X509 server certificates with highest security standards (4096-bit certificates) which additionally affected performance in a negative way. Nevertheless, once MQTT clients are connected, there isn’t significant performance overhead for 50.000 MQTT clients that are handling 10.000 messages per second with QoS 1, disk persistence and 50.000 distinct topics.
Tips for further reducing TLS overhead:
- Using a Load Balancer with SSL Termination. Many Load Balancers support SSL offloading which can increase performance significantly.
- SSL Session Resumption with Session IDs can be used to avoid a complete TLS handshake when a MQTT client reconnects. Bear in mind that session resumption is most secure when using cipher suites that have Perfect Forward Secrecy characteristics.
- X509 certificates with smaller key length (e.g. 1024-bit or 2048-bit) could be used.
- Elliptic Curve Cryptography (ECC) could potentially reduce CPU consumption.
If you want to learn more about the benchmark, including all details, you can download the benchmark document for free.
What are your experiences with MQTT and TLS? Tell us in the comments!