The RabbitMQ has new exchange type which allows for delayed message delivery. You can read more about the Delayed Message plugin here and here.
The exchange works by checking message headers to determine whether the message has to be delayed, and then store message in Mnesia (RabbitMQ’s database) if necessary. All this will have an impact on performance of the exchange. To see how big the impact is, I decided to run some tests.
Lets see how the new exchange performs when publishing messages which do not require delaying. Below graph shows publishing rate when there is one queue and not consumers. The average for Direct exchange was 17.5K messages per second, while the delayed exchange averaged 14K meaning that it was about 20% slower.
Now lets see how this changes when there are enough consumers to provide 100% queue utilisation. This time regular exchange was averaging 25K while delayed one did 22K, being only 12% slower.
Next, was time for testing delayed messages. I set delay first to 30 seconds, then to 90 seconds. We can notice drastic drop in performance, about 60%, with delayed exchange averaging 6.3K messages per second. There is even further drop in performance once the messages become due to be delivered (at 30 or 90 seconds).
Delayed messages publish rate when there are no consumers.
Delayed messages publish rate with 100% consumer utilisation.
For testing I used Azure Virtual Machines. All messages had the same size of 100 bytes.
The server configuration was:
- Windows Server 2012 R2 Datacenter, D4 instance with 8 cores CPU and 24 GB RAM
- RabbitMQ 3.5.1
- Erlang 17.5 (64-bit)
- Windows Server 2012 R2 Datacenter, A2 instance with 2 cores and 8 GB RAM
- application written in C# using client library ver. 3.5.1
Below table illustrates my findings:
|EXCHANGE TYPE||NO CONSUMERS||100% UTILISATION|
|delayed||14.0K 20%||22.0K 12%|
|delayed (30)||6.3K 64%||6.4K 75%|
|delayed (90)||6.3K 64%||6.2K 75%|
It is expected that the new exchange will be slower, with that all extra house keeping. General advice is to use it only for delayed messages. In case the queue needs to consume both message types (regular and delayed), there are two solutions:
- either bind queue to both exchanges
- or bind queue to regular exchange, and bind regular exchange to delayed