Skip to main content
Version: 1.0.x

Test Report

Test Objectives

To evaluate the performance metrics of BifroMQ Standalone Edition, including response times and resource consumption under different message throughput scenarios.

Test Tools and Environment

Test Tools

The test tools were developed based on vertx-mqtt, which provides flexibility in usage and demonstrates excellent performance.

Test Environment

  • BifroMQ Deployment Machine: CentOS release 7.6, 32 cores, 128GB memory (JVM configured with 40GB memory).
  • Load Generation Machine: CentOS release 7.6, 32 cores, 128GB memory (JVM configured with 32GB memory).

Test Scenarios

This test report mainly focuses on message throughput testing. The test dimensions include:

  • Publisher & Subscriber Ratio: 1 to 1, 1 to many
  • cleanSession Configuration: true | false
  • QoS (Quality of Service): 0 | 1 | 2
  • Payload Size: 32b | 1024b
  • Message Frequency per Connection: Ranging from 1 to 100
  • Shared Subscriptions

Each test scenario is comprised of combinations from the dimensions listed above.

Test Results

The Scenario name is derived from the combination of parameters from the test cases.

The name "100_100_qos0_p1024_50mps" represents the following:

  • 100 Pub MQTT clients
  • 100 Sub MQTT clients
  • Messages use QoS0
  • Single message payload size is 1024 bytes
  • A single Pub client sends 50 messages per second to BifroMQ

Explanation of Parameters:

ParameterDescription
CTotal number of MQTT connections in test cases.
m/sNumber of messages sent to BifroMQ per second.
msMessage response time from Pub to Sub, measured in milliseconds.

Result description

  1. When cleanSession=true, the highest message throughput in high-frequency scenarios can reach over 200,000 messages per second, and in low-frequency scenarios it can reach over 100,000 messages per second.

  2. When cleanSession=false, the highest message throughput in high-frequency scenarios can reach over 15,000 messages per second, and in low-frequency scenarios it can reach over 10,000 messages per second.

  3. The response time from the publishing end to the subscribing end is in the millisecond range, and the CPU load remains low.

  4. The system throughput and latency performance are greatly influenced by the QoS (Quality of Service). The difference between QoS0 and QoS1 scenarios is not significant, while QoS2 scenarios are more affected due to the complexity of the protocol itself.

  5. In some test scenarios, the latency data of the first sampling point in the attached images is significantly larger. This is caused by the sudden increase in pressure due to cold-starting the test case without pre-warming. This situation will not occur during smooth operation of the service.

  6. There is a significant difference in performance results between cleanSession=false and cleanSession=true scenarios. This is because the architecture of BifroMQ is designed for building serverless cloud services, and the reliability of offline messages is an important SLA indicator for cloud services. Therefore, BifroMQ chose a disk-based persistence strategy instead of in-memory storage, ensuring that data is not lost during crashes or restarts. The performance of offline message storage in the standalone version is limited by the local disk IO performance of the current testing machine. By using high-performance disks or implementing suitable load balancing strategies in a clustered environment, performance can be effectively improved.

High-frequency Scenario with cleanSession=true

QoS 0 Scenario

Scenario CombinationQoSMPS per ConnectionPayload (bytes)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU Usage
100_100_qos0_p1024_50mps05010242005k0.310.432.5%
1k_1k_qos0_p1024_50mps05010242k50k0.421.3021%
2k_2k_qos0_p32_100mps0100324k200k2.3815.7240%
4k_4k_qos0_p32_50mps050328k200k6.6548.2331%
5k_5k_qos0_p32_50mps0503210k226k12.5156.6130%
Graphs for the 4k_4k_qos0_p32_50mps Scenario:

QPS Graph Mean Response Time Graph P99 Response Time Graph Max Response Time Graph

QoS 1 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
100_100_qos1_p1024_50mps15010242005k0.270.422.6%
1k_1k_qos1_p1024_50mps15010242k50k0.491.8923%
2k_2k_qos1_p32_100mps1100324k182k20.89218.138%
4k_4k_qos1_p32_50mps150328k179k31.35352.3126%
5k_5k_qos1_p32_50mps1503210k189k54.43419.4236%
Graphs for the 2k_2k_qos1_p32_50mps Scenario:

qps mean p99 max

QoS 2 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
1.2k_1.2k_qos2_p32_50mps2100322.4k120k7.0841.9340%
2k_2k_qos2_p32_100mps2100324k138k38.02201.3140%
2k_1.2k_qos2_p32_50mps Graphs 1for the Scenario:

qps mean p99 max

Low-frequency Scenario with cleanSession=true

QoS 0 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
50k_50k_qos0_p1024_1mps011024100k50k0.854.1623%
100k_100k_qos0_p1024_1mps011024200k100k13.54209.6840%
Graphs for the 100k_100k_qos0_p1024_1mps Scenario:

qps mean p99 max

QoS 1 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
50k_50k_qos1_p1024_1mps111024100k50k5.5514.1232%
100k_100k_qos1_p1024_1mps111024200k100k27.36603.9530%
Graphs for the 100k_100k_qos1_p1024_1mps Scenario:

qps mean p99 max

QoS 2 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
50k_50k_qos2_p1024_1mps211024100k50k25.32184.4825%
Graphs for the 50k_50k_qos2_p1024_1mps Scenario:

qps mean p99 max

Shared subscription scenario with cleanSession=true

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
40k_400_qos0_p1024_1mps011024400.4k40k0.323.4018%
40k_400_qos1_p1024_1mps111024400.4k40k0.616.8119%
40k_400_qos2_p1024_1mps211024400.4k40k0.817.0623%
Graphs for the 40k_400_qos2_p1024_1mps Scenario:

qps mean p99 max

Shared subscription scenario cleanSession=false

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
5k_50_qos0_p1024_1mps01102450505k7.2230.387%
5k_50_qos1_p1024_1mps11102450505k6.7927.237%
5k_50_qos2_p1024_1mps21102450505k16.2456.567%
Graphs for the 5k_50_qos2_p1024_1mps Scenario:

qps mean p99 max

fanOut scenario with cleanSession=true

A small number of clients act as Publishers, and a large number of clients subscribe to the same topic as Subscribers, forming a scenario in which each message is broadcast by a massive fanOut.

Scenario CombinationQoSMPS per ConnectionPayload(byte)PubNumber of Connections (C)Number of Sub connectionsPublish m/sSubscribe m/sAverage Response Time (ms)P99 Response Time (ms)CPU
1_1k_qos1_p32_1mps113211k11k6184%
Graphs for the 1_1k_qos1_p32_1mps Scenario:

qps mean p99 max

Low-frequency Scenario with cleanSession=false 1v1

QoS 0 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
1k_1k_qos0_p32_1mps01322k1k1.32.26%
1k_1k_qos0_p1024_1mps0110242k1k1.42.36%
5k_5k_qos0_p32_1mps013210k5k2.75.218%
5k_5k_qos0_p1024_1mps01102410k5k3.06.518%
10k_10k_qos0_p32_1mps013220k10k9.62926%
10k_10k_qos0_p1024_1mps01102420k10k216326%
Graphs for the 10k_10k_qos0_p32_1mps Scenario:

qps mean p99 max

Graphs for the 10k_10k_qos0_p1024_1mps Scenario:

qps mean p99 max

QoS 1 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)Resident MemoryCPU
1k_1k_qos1_p32_1mps11322k1k1.42.38%
1k_1k_qos1_p1024_1mps1110242k1k1.42.38%
5k_5k_qos1_p32_1mps113210k5k3.27.020%
5k_5k_qos1_p1024_1mps11102410k5k3.17.620%
10k_10k_qos1_p32_1mps113220k10k133030%
10k_10k_qos1_p1024_1mps11102420k10k4911730%
Graphs for the 10k_10k_qos1_p32_1mps Scenario:

qps mean p99 max

Graphs for the 10k_10k_qos1_p1024_1mps Scenario:

qps mean p99 max

QoS 2 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)CPU
1k_1k_qos2_p32_1mps21322k1k1.62.88%
1k_1k_qos2_p1024_1mps2110242k1k1.73.08%
5k_5k_qos2_p32_1mps213210k5k3.88.322%
5k_5k_qos2_p1024_1mps21102410k5k8.24022%
7k_7k_qos2_p32_1mps213214k7k9.62824%
7k_7k_qos2_p1024_1mps21102414k7k155024%
Graphs for the 7k_7k_qos2_p32_1mps Scenario:

qps mean p99 max

Graphs for the 7k_7k_qos2_p1024_1mps Scenario:

qps mean p99 max

High-frequency Scenario with cleanSession=false 1v1

QoS 0 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)Resident MemoryCPU
20_20_qos0_p32_50mps05032401k11968%
20_20_qos0_p1024_50mps0501024401k211178%
100_100_qos0_p32_50mps050322005k238414%
100_100_qos0_p1024_50mps05010242005k289214%
200_200_qos0_p32_50mps0503240010k4711318%
200_200_qos0_p1024_50mps050102440010k5813018%
300_300_qos0_p32_50mps0503260015k6714222%
300_300_qos0_p1024_50mps050102460015k9018422%
Graphs for the 300_300_qos0_p32_50mps Scenario:

qps mean p99 max

Graphs for the 300_300_qos0_p1024_50mps Scenario:

qps mean p99 max

QoS 1 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)Resident MemoryCPU
20_20_qos1_p32_50mps15032401k4.63810%
20_20_qos1_p1024_50mps1501024401k2011710%
100_100_qos1_p32_50mps150322005k269220%
100_100_qos1_p1024_50mps15010242005k3210120%
200_200_qos1_p32_50mps1503240010k5815123%
200_200_qos1_p1024_50mps150102440010k7221023%
300_300_qos1_p32_50mps1503260015k8121028%
300_300_qos1_p1024_50mps150102460015k10726028%
Graphs for the 300_300_qos1_p32_50mps Scenario:

qps mean p99 max

Graphs for the 300_300_qos1_p1024_50mps Scenario:

qps mean p99 max

QoS 2 Scenario

Scenario CombinationQoSMPS per ConnectionPayload(byte)Number of Connections (C)Total Messages per SecondAverage Response Time (ms)P99 Response Time (ms)Resident MemoryCPU
20_20_qos2_p32_50mps05032401k167510%
20_20_qos2_p1024_50mps0501024401k199210%
100_100_qos2_p32_50mps050322005k379215%
100_100_qos2_p1024_50mps05010242005k4410915%
Graphs for the 100_100_qos2_p32_50mps Scenario:

qps mean p99 max

Graphs for the 100_100_qos2_p1024_50mps Scenario:

qps mean p99 max

System Parameter Optimization

The following Kernel parameters can affect the maximum number of connections that the machine hosting BifroMQ can accept.

Memory

  • vm.max_map_count: Limits the number of VMAs (Virtual Memory Areas) that a process can have. It can be increased to 221184.

Maximum Open Files

  • nofile: Specifies the maximum number of files that a single process can open.
  • nr_open: Specifies the maximum number of files that can be allocated per process, usually defaulting to 1024 * 1024 = 1048576.
  • file-max: Specifies the maximum number of files that the system kernel can open, with a default value of 185745.

NetFilter Tuning

Use sysctl -a | grep conntrack to view the current parameters. The following parameters determine the maximum number of connections:

  • net.netfilter.nf_conntrack_buckets: The size of the hashtable buckets that record connection entries.
    • Modification command: echo 262144 > /sys/module/nf_conntrack/parameters/hashsize
  • net.netfilter.nf_conntrack_max: The maximum number of entries in the hashtable, generally equal to nf_conntrack_buckets * 4.
  • net.nf_conntrack_max: Same as net.netfilter.nf_conntrack_max.
  • net.netfilter.nf_conntrack_tcp_timeout_fin_wait: Default 120s -> Recommended 30s.
  • net.netfilter.nf_conntrack_tcp_timeout_time_wait: Default 120s -> Recommended 30s.
  • net.netfilter.nf_conntrack_tcp_timeout_close_wait: Default 60s -> Recommended 15s.
  • net.netfilter.nf_conntrack_tcp_timeout_established: Default 432000 seconds (5 days) -> Recommended 300s.

The following sysctl parameters can affect the performance of TCP channels under high load:

It is recommended to use the CentOS 7 environment for deployment and stress testing.

For CentOS 6, system parameter tuning is required:

  • net.core.wmem_max: Maximum TCP data send window size (bytes).
    • Modification command: echo 'net.core.wmem_max=16777216' >> /etc/sysctl.conf
  • net.core.wmem_default: Default TCP data send window size (bytes).
    • Modification command: echo 'net.core.wmem_default=262144' >> /etc/sysctl.conf
  • net.core.rmem_max: Maximum TCP data receive window size (bytes).
    • Modification command: echo 'net.core.rmem_max=16777216' >> /etc/sysctl.conf
  • net.core.rmem_default: Default TCP data receive window size (bytes).
    • Modification command: echo 'net.core.rmem_default=262144' >> /etc/sysctl.conf
  • net.ipv4.tcp_rmem: Memory usage of the socket receive buffer - minimum, warning, maximum.
    • Modification command: echo 'net.ipv4.tcp_rmem= 1024 4096 16777216' >> /etc/sysctl.conf
  • net.ipv4.tcp_wmem: Memory usage of the socket send buffer - minimum, warning, maximum.
    • Modification command: echo 'net.ipv4.tcp_wmem= 1024 4096 16777216' >> /etc/sysctl.conf
  • net.core.optmem_max: The maximum buffer size (in bytes) allowed for each socket.
    • Modification command: echo 'net.core.optmem_max = 16777216' >> /etc/sysctl.conf
  • net.core.netdev_max_backlog: The length of the queue into which network device places requests.
    • Modification command:echo 'net.core.netdev_max_backlog = 16384' >> /etc/sysctl.conf

After making the modifications, use sysctl -p and restart the server for them to take effect.