NanoMQ v0.21.1 Release Note

Jan 29, 2024

NanoMQ 0.21.1 is a republish of 0.21.0 in order to bring some important fixes such as :

This Major release has two big new features: MQTT Stream and a New Plugin system along with multiple important fixes and minor new features.

  1. Read bridging backoff time from the conf file.
  2. Add rpath support, allow users to specify their own so file to link
  3. Fix Bridging aio overflow while using HTTP Publish API with bridging
  4. Add a dependency checker for DDS Proxy to ensure both sides using the same ver of CycloneDDS
  5. Fix a stack overflow bug caused by compiler optimization
  6. Expose TCP level option for MQTT TCP bridging
  7. Add a new Plugin system. It allows the user to set a self-defined user property.
  8. Add a new conf option to disable/enable MQTT TCP listener
  9. Fix a potential decoding bug of a large CONNECT Packet
  10. Sync NNG with Upstream to fix the duplicated ClientID issue.
  11. Add a brand new Messaging Queue feature: MQTT Stream, which automatically partitions MQTT msgs to disk. Allows consuming msg via NNG Req/Rep Sock.


A basic version of MQ : MQTT STREAM has been released, and its main ability is to persist the content of mqtt messages, for consumer to retrieve msgs by key.


First we introduce three data structures for MQTT STREAM.

  • exchange_server/exchange/ringbus

The specific reference configuration is as follows.

exchange_client.mq1 {
    # # exchanges contains multiple MQ exchanger
    exchange {
        # # MQTT Topic for filtering messages and saving to queue
        topic = "exchange/topic1",
        # # MQ name
        name = "exchange_no1",
        # # MQ category. Only support Ringbus for now
        ringbus = {
            # # ring buffer name
            name = "ringbus",
            # # max length of ring buffer (msg count)
            cap = 1000
            fullOp = 3


  • The topic indicates which topic you want to put data in ringbus.
  • Where fullOp is a key attribute and represents the operation when the ringbus is full.
    • 0: RB_FULL_NONE: When the ringbus is full, no action is taken and the message enqueue fail
    • 1: RB_FULL_DROP: When the ringbus is full, the data in the ringbus is discarded
    • 2: RB_FULL_RETURN: When the ringbus is full, the data in the ringbus is taken out and returned to the aio
    • 3: RB_FULL_FILE: When the ringbus is full, the data in the ringbus is written to the file

For example, when the ringbus is full and you want to store the data to a file, you should use fullOp=3

Messages in ringbus

Messages in ringbus are stored in the form of key/value, and currently the key is calculated using hash(clientid+topic+id).

How to query messages

If you want to query messages stored in a file, there's an interface, as well as a consumer demo.

  • First compile exchange_consumer. You can find the source code at

  • Use exchange_consumer

  1. dump the msg data of all files.
    ./demo/exchange_consumer/exchange_consumer "dumpfile"
  2. dump the msg data from the file according to the key.
    ./demo/exchange_consumer/exchange_consumer "dumpkey:4862831023852633869"
  3. dump the msg data from the file according to the keys.
    ./demo/exchange_consumer/exchange_consumer "dumpkeys:2062146488009373518,2625100014974548622"

What's Changed in NanoMQ

New Contributors

Full Changelog:

What's Changed in NanoNNG

EMQX Cloud

Fully managed MQTT messaging service.

14 Days Free Trial →

Learn MQTT Protocol

The rich and easy-to-understand MQTT guide to help you quickly get started with MQTT protocol.

Learn More →