Features

The broker was built as a working tool: everything listed below is configured in the dashboard and applies without a restart.

Protocol

Both versions at once

MQTT 3.1.1 and MQTT 5.0 run simultaneously on the same port, and clients of either version exchange messages freely. The codec encodes and decodes all 15 packet types and validates Variable Byte Integer bounds, duplicate properties and reserved bits.

QoS 0, 1 and 2

Full handshakes, duplicate suppression on QoS 2, and redelivery of unfinished exchanges after a reconnect. Offline queues of persistent sessions survive a broker restart.

Retain and Last Will

A retained-message store with clearing by empty payload, including whole branches, plus Retain Handling 0/1/2 and Retain As Published. The will is sent in every disconnect scenario, including version 5's Will Delay Interval.

Version 5 capabilities

Topic aliases in both directions, Session Expiry, Receive Maximum and flow control, Maximum Packet Size, subscription identifiers, shared subscriptions via $share, No Local, Message Expiry, Payload Format Indicator with UTF-8 validation, Content Type, Response Topic, Correlation Data, User Properties, reason codes in every packet, server-side DISCONNECT and the AUTH packet.

$SYS system topics

Version, uptime and counters for clients, messages, bytes and errors are published as retained messages. The branch is closed by default: wildcards do not reach $ topics, anonymous clients are denied the whole namespace, and a switch in the settings turns publishing off entirely.

Web dashboard

Overview

Summary tiles, machine health (CPU, memory, and the disk holding the data directory), live charts of message rate, traffic and connections, active topics, listeners and an event feed.

Clients and topics

A session table with a per-client card, plus disconnecting and deleting sessions. Separately: active subscriptions with all MQTT 5.0 options and the contents of the retained store.

Traffic and publishing

A live stream of messages and broker events with filtering and pause. You can publish a message with every version 5 property straight from the dashboard — handy when debugging devices.

Seven languages, two themes

Russian, English, German, Spanish, French, Italian and Chinese. Dark and light themes switch on the fly, and the choice is remembered as the dashboard default.

Built-in help

A guide with a table of contents right inside the dashboard, translated into all seven languages — no need to hunt for documentation elsewhere.

Access and security

Two independent circuits

There is one dashboard administrator, defined in config.json, and they manage only the web interface. MQTT devices are a separate list of accounts with their own passwords and permissions. Creating an MQTT user named after the administrator is rejected.

Topic ACLs

A rule is a filter, an access mode (read, write, readwrite) and an allow or deny decision. Rules are checked top to bottom until the first match, and everything is deny-by-default. The $u placeholder expands to the client's own name, so the rule $u/# confines every device to its own branch. Rule order is changed by dragging.

Six credential sources

The built-in list, MySQL/MariaDB (an EMQX-style schema), SQLite, CSV with file reloading, JWT and an external HTTP service. The source is switched right in the dashboard: first verified with the Test button, then applied live.

Hashes, not passwords

Passwords are stored as PBKDF2-HMAC-SHA256 with 210,000 iterations and a random salt. Session and API tokens are stored as hashes only. External sources understand plain, sha256, sha512, bcrypt and pbkdf2.

TLS out of the box

A self-signed certificate is generated on first run so that :8883 works immediately. For production, put your own certificate in the config.

Rules and flows

Topic rewrite

A topic name is substituted on the fly on publish, on subscribe or always: an MQTT filter for cheap selection, a regular expression, and a destination template with groups $1…$9. %u and %c are available, the $share prefix is preserved, and UNSUBSCRIBE goes through the same rewrite. The dashboard has a sandbox for testing a rule.

Auto-subscribe

A client gets its subscriptions right after connecting, with no SUBSCRIBE. %u and %c and every version 5 option are supported, and ACLs are checked as usual — a forbidden rule is silently skipped and the connection is not dropped.

Topic limits

A per-topic-pattern rule thins a stream down to a rate or drops it entirely. Thinning keeps the latest value: a sensor sending ten times a second becomes one message per second — the freshest one. The rule card shows how many messages matched, passed and were dropped.

Flood control

A token bucket per connection: messages per second, burst, bytes per second, byte burst. Exceeding it neither drops the connection nor loses messages — the broker pauses before the next socket read, TCP closes the window, and the sender slows down on its own.

Delayed publish

The topic $delayed/{seconds}/{topic} is held by the broker until it is due, EMQX-compatible. The interval ranges from a second to 49 days, the acknowledgement arrives immediately, and the queue survives a restart and is visible in the dashboard with a countdown.

Integration

Broker-to-broker bridging

The broker connects as a client to another MQTT broker and forwards topics in both directions. The address, login, TLS, protocol version and rules of filter + direction + QoS + prefixes are all configurable. There is loop protection, automatic reconnect, No Local on version 5 and counters in the dashboard.

REST API

Everything the dashboard does is available with a bearer token: statistics, clients, subscriptions, retained messages, publishing, events, users, settings, bridges, rules, delayed messages, import and export. A token can be issued read-only.

Device provisioning from your system

POST /api/users creates a device together with its permissions, PATCH changes the password or ACL, DELETE removes it. Changes apply instantly: the broker drops that user's live connections itself so the new rules take effect right away.

MQTT over WebSocket

The mqtt subprotocol on the same port as the dashboard — browser clients connect without a separate gateway. RFC 6455 implemented on top of net/http, with no dependencies.

Import and export

Settings, users and rules are exported as one file and loaded back — moving to another server needs no manual repetition.

Operations

One file, no dependencies

A statically linked pure-Go binary: no runtime, no libc, no external database. It runs on Debian and Ubuntu out of the box and builds for amd64, arm64 and armhf.

SQLite storage

Retained messages are written immediately on every change, persistent sessions are snapshotted every ten seconds and on shutdown, and delayed messages are written when queued. Anything expired is discarded at startup, and a state restored line goes to the log.

Machine health

CPU load, used memory and free space on the data disk — computed with the standard library, without cgo, in separate implementations for Linux and Windows. The bar turns amber past 75% and red past 90%.

systemd and nginx

A systemd unit, an nginx config and an idempotent install script are included: the dashboard listens on localhost only and is published through nginx, while the MQTT ports work directly.

Build stamp

The version, build number and build time are baked into the binary and visible in the dashboard, in the About section and via the -version flag — you always know exactly what is running.

All of it, free

There are no limits on devices, messages or subscriptions.

Download the broker