Skip to content

emqx/emqtt-bench

master
Switch branches/tags
Code

Erlang MQTT Benchmark Tool

emqtt_bench is a simple MQTT v5.0 benchmark tool written in Erlang.

You can download pre-built binary packeges from https://github.com/emqx/emqtt-bench/releases.

Build from source code

NOTE: Requires Erlang/OTP 22.3+ to build.

Install dependencies

emqtt-bench requires libatomic

# centos 7
sudo yum install libatomic
# ubuntu 20.04
sudo apt install libatomic1 

make

git clone https://github.com/emqx/emqtt-bench.git
cd emqtt-bench
make

Optional, you could disable QUIC support if you have problem with compiling

BUILD_WITHOUT_QUIC=1 make

Connect Benchmark

$ ./emqtt_bench conn --help
Usage: emqtt_bench conn [--help <help>] [-d <dist>] [-h [<host>]]
                        [-p [<port>]] [-V [<version>]] [-c [<count>]]
                        [-n [<startnumber>]] [--load-qst <nst_dets_file>]
                        [-Q [<qoe>]] [-i [<interval>]] [-u <username>]
                        [-P <password>] [-k [<keepalive>]] [-C [<clean>]]
                        [-x [<expiry>]] [-S [<ssl>]]
                        [--certfile <certfile>] [--keyfile <keyfile>]
                        [--quic [<quic>]] [--ifaddr <ifaddr>]
                        [--prefix <prefix>] [-s [<shortids>]]
                        [-l <lowmem>]
                        [--num-retry-connect [<num_retry_connect>]]
                        [-R [<conn_rate>]]
                        [--force-major-gc-interval [<force_major_gc_interval>]]
                        [--log_to [<log_to>]]

  --help                     help information
  -d, --dist                 enable distribution port
  -h, --host                 mqtt server hostname or comma-separated 
                             hostnames [default: localhost]
  -p, --port                 mqtt server port number [default: 1883]
  -V, --version              mqtt protocol version: 3 | 4 | 5 [default: 5]
  -c, --count                max count of clients [default: 200]
  -n, --startnumber          start number [default: 0]
  -Q, --qoe                  Enable QoE tracking [default: false]
  -i, --interval             interval of connecting to the broker 
                             [default: 10]
  -u, --username             username for connecting to server
  -P, --password             password for connecting to server
  -k, --keepalive            keep alive in seconds [default: 300]
  -C, --clean                clean session [default: true]
  -x, --session-expiry       Set 'Session-Expiry' for persistent sessions 
                             (seconds) [default: 0]
  -S, --ssl                  ssl socoket for connecting to server 
                             [default: false]
  --certfile                 client certificate for authentication, if 
                             required by server
  --keyfile                  client private key for authentication, if 
                             required by server
  --quic                     QUIC transport [default: false]
  --load-qst                 load quic session tickets from dets file
  --ifaddr                   local ipaddress or interface address
  --prefix                   client id prefix
  -s, --shortids             use short ids for client ids [default: false]
  -l, --lowmem               enable low mem mode, but use more CPU
  --num-retry-connect        number of times to retry estabilishing a 
                             connection before giving up [default: 0]
  -R, --connrate             connection rate(/s), default: 0, fallback to 
                             use --interval [default: 0]
  --force-major-gc-interval  interval in milliseconds in which a major GC 
                             will be forced on the bench processes.  a 
                             value of 0 means disabled (default).  this 
                             only takes effect when used together with 
                             --lowmem. [default: 0]
  --log_to                   Control where the log output goes. console: 
                             directly to the console      null: quietly, 
                             don't output any logs. [default: console]

For example, create 50K concurrent connections at the arrival rate of 100/sec:

./emqtt_bench conn -c 50000 -i 10

Sub Benchmark

$ ./emqtt_bench sub --help
Usage: emqtt_bench sub [--help <help>] [-d <dist>] [-h [<host>]]
                       [-p [<port>]] [-V [<version>]] [-c [<count>]]
                       [-n [<startnumber>]] [-i [<interval>]]
                       [-t <topic>] [-q [<qos>]]
                       [--load-qst <nst_dets_file>] [-Q [<qoe>]]
                       [-u <username>] [-P <password>] [-k [<keepalive>]]
                       [-C [<clean>]] [-x [<expiry>]] [-S [<ssl>]]
                       [--certfile <certfile>] [--keyfile <keyfile>]
                       [--ws [<ws>]] [--quic [<quic>]]
                       [--ifaddr <ifaddr>] [--prefix <prefix>]
                       [-s [<shortids>]] [-l <lowmem>]
                       [--num-retry-connect [<num_retry_connect>]]
                       [-R [<conn_rate>]]
                       [--force-major-gc-interval [<force_major_gc_interval>]]
                       [--log_to [<log_to>]]

  --help                     help information
  -d, --dist                 enable distribution port
  -h, --host                 mqtt server hostname or comma-separated 
                             hostnames [default: localhost]
  -p, --port                 mqtt server port number [default: 1883]
  -V, --version              mqtt protocol version: 3 | 4 | 5 [default: 5]
  -c, --count                max count of clients [default: 200]
  -n, --startnumber          start number [default: 0]
  -i, --interval             interval of connecting to the broker 
                             [default: 10]
  -t, --topic                topic subscribe, support %u, %c, %i variables
  -q, --qos                  subscribe qos [default: 0]
  -Q, --qoe                  Enable QoE tracking [default: false]
  -u, --username             username for connecting to server
  -P, --password             password for connecting to server
  -k, --keepalive            keep alive in seconds [default: 300]
  -C, --clean                clean start [default: true]
  -x, --session-expiry       Set 'Session-Expiry' for persistent sessions 
                             (seconds) [default: 0]
  -S, --ssl                  ssl socoket for connecting to server 
                             [default: false]
  --certfile                 client certificate for authentication, if 
                             required by server
  --keyfile                  client private key for authentication, if 
                             required by server
  --ws                       websocket transport [default: false]
  --quic                     QUIC transport [default: false]
  --load-qst                    load quic session tickets from dets file  
  --ifaddr                   local ipaddress or interface address
  --prefix                   client id prefix
  -s, --shortids             use short ids for client ids [default: false]
  -l, --lowmem               enable low mem mode, but use more CPU
  --num-retry-connect        number of times to retry estabilishing a 
                             connection before giving up [default: 0]
  -R, --connrate             connection rate(/s), default: 0, fallback to 
                             use --interval [default: 0]
  --force-major-gc-interval  interval in milliseconds in which a major GC 
                             will be forced on the bench processes.  a 
                             value of 0 means disabled (default).  this 
                             only takes effect when used together with 
                             --lowmem. [default: 0]
  --log_to                   Control where the log output goes. console: 
                             directly to the console      null: quietly, 
                             don't output any logs. [default: console]

For example, create 50K concurrent connections at the arrival rate of 100/sec:

./emqtt_bench sub -c 50000 -i 10 -t bench/%i -q 2

Pub Benchmark

./emqtt_bench pub --help
Usage: emqtt_bench pub [--help <help>] [-d <dist>] [-h [<host>]]
                       [-p [<port>]] [-V [<version>]] [-c [<count>]]
                       [-n [<startnumber>]] [-i [<interval>]]
                       [-I [<interval_of_msg>]] [-u <username>]
                       [-P <password>] [-t <topic>] [-s [<size>]]
                       [-m <message>] [-q [<qos>]] [-Q [<qoe>]]
                       [--load-qst <nst_dets_file>] [-r [<retain>]]
                       [-k [<keepalive>]] [-C [<clean>]] [-x [<expiry>]]
                       [-L [<limit>]] [-S [<ssl>]]
                       [--certfile <certfile>] [--keyfile <keyfile>]
                       [--ws [<ws>]] [--quic [<quic>]]
                       [--ifaddr <ifaddr>] [--prefix <prefix>]
                       [-s [<shortids>]] [-l <lowmem>] [-F [<inflight>]]
                       [-w [<wait_before_publishing>]]
                       [--max-random-wait [<max_random_wait>]]
                       [--min-random-wait [<min_random_wait>]]
                       [--num-retry-connect [<num_retry_connect>]]
                       [-R [<conn_rate>]]
                       [--force-major-gc-interval [<force_major_gc_interval>]]
                       [--log_to [<log_to>]]

  --help                        help information
  -d, --dist                    enable distribution port
  -h, --host                    mqtt server hostname or comma-separated 
                                hostnames [default: localhost]
  -p, --port                    mqtt server port number [default: 1883]
  -V, --version                 mqtt protocol version: 3 | 4 | 5 [default: 
                                5]
  -c, --count                   max count of clients [default: 200]
  -n, --startnumber             start number [default: 0]
  -i, --interval                interval of connecting to the broker 
                                [default: 10]
  -I, --interval_of_msg         interval of publishing message(ms) 
                                [default: 1000]
  -u, --username                username for connecting to server
  -P, --password                password for connecting to server
  -t, --topic                   topic subscribe, support %u, %c, %i, %s 
                                variables
  -s, --size                    payload size [default: 256]
  -m, --message                 set the message content for publish
  -q, --qos                     subscribe qos [default: 0]
  -Q, --qoe                     Enable QoE tracking [default: false]
  -r, --retain                  retain message [default: false]
  -k, --keepalive               keep alive in seconds [default: 300]
  -C, --clean                   clean start [default: true]
  -x, --session-expiry          Set 'Session-Expiry' for persistent 
                                sessions (seconds) [default: 0]
  -L, --limit                   The max message count to publish, 0 means 
                                unlimited [default: 0]
  -S, --ssl                     ssl socoket for connecting to server 
                                [default: false]
  --certfile                    client certificate for authentication, if 
                                required by server
  --keyfile                     client private key for authentication, if 
                                required by server
  --ws                          websocket transport [default: false]
  --quic                        QUIC transport [default: false]
  --load-qst                    load quic session tickets from dets file
  --ifaddr                      One or multiple (comma-separated) source 
                                IP addresses
  --prefix                      client id prefix
  -s, --shortids                use short ids for client ids [default: 
                                false]
  -l, --lowmem                  enable low mem mode, but use more CPU
  -F, --inflight                maximum inflight messages for QoS 1 an 2, 
                                value 0 for 'infinity' [default: 1]
  -w, --wait-before-publishing  wait for all publishers to have (at least 
                                tried to) connected before starting 
                                publishing [default: false]
  --max-random-wait             maximum randomized period in ms that each 
                                publisher will wait before starting to 
                                publish (uniform distribution) [default: 0]
  --min-random-wait             minimum randomized period in ms that each 
                                publisher will wait before starting to 
                                publish (uniform distribution) [default: 0]
  --num-retry-connect           number of times to retry estabilishing a 
                                connection before giving up [default: 0]
  -R, --connrate                connection rate(/s), default: 0, fallback 
                                to use --interval [default: 0]
  --force-major-gc-interval     interval in milliseconds in which a major 
                                GC will be forced on the bench processes.  
                                a value of 0 means disabled (default).  
                                this only takes effect when used together 
                                with --lowmem. [default: 0]
  --log_to                      Control where the log output goes. 
                                console: directly to the console      
                                null: quietly, don't output any logs. 
                                [default: console]

For example, create 100 connections and each publishes messages at the rate of 100 msg/sec.

./emqtt_bench pub -c 100 -I 10 -t bench/%i -s 256

Local interface

./emqtt_bench pub --ifaddr 192.168.1.10
./emqtt_bench sub --ifaddr 192.168.2.10

TLS/SSL (cliet certificate is not required by server)

./emqtt_bench sub -c 100 -i 10 -t bench/%i -p 8883 --ssl
./emqtt_bench pub -c 100 -I 10 -t bench/%i -p 8883 -s 256 --ssl

TLS/SSL (client certificate is required by server)

./emqtt_bench sub -c 100 -i 10 -t bench/%i -p 8883 --ssl --certfile path/to/client-cert.pem --keyfile path/to/client-key.pem
./emqtt_bench pub -c 100 -i 10 -t bench/%i -s 256 -p 8883 --ssl --certfile path/to/client-cert.pem --keyfile path/to/client-key.pem

Notice

You should not set '-c' option more than 64K for TCP ports limit on one source addresses, however you can send messages from multiple source IP Addresses with '--ifaddr ' such like

./emqtt_bench sub -c 200000 -t "perf/test" --ifaddr 192.168.200.18,192.168.200.19,192.168.200.20,192.168.200.21

Make sure to increase resource usage limits and expand the port range like following on Linux.

ulimit -n 200000
sudo sysctl -w net.ipv4.ip_local_port_range="1025 65534"

Author

EMQ X Team.