MQTT is the standard protocol for IoT messaging, but existing brokers are server-class software. They assume abundant memory, a full OS, and dynamic memory allocation. Embedded devices, gateways, and safety-critical platforms don’t have those luxuries. Teams building edge gateways, local message routing, or offline-capable IoT systems have had to work around this gap.
wolfMQTT now fills it. The library includes a purpose-built MQTT broker written in C and designed for portability to embedded systems including bare-metal. It provides hardware abstraction layers for networking and time. An optional static memory mode eliminates all dynamic allocation, making it suitable for RTOS environments, bare-metal systems, and safety-critical applications.
Portable by Design
The broker has no hard dependencies on Linux, POSIX, or any specific TCP/IP stack. All network operations go through a simple callback interface (listen, accept, read, write, close), with three backends included:
- POSIX sockets: Linux, macOS, BSD
- wolfIP: embedded TCP/IP stack, no OS required
- Custom callbacks: bring your own platform
Time, sleep, and socket types are also abstracted, so porting requires no changes to the broker core.
Static Memory Mode
With WOLFMQTT_STATIC_MEMORY enabled, the broker makes zero dynamic allocations. All clients, subscriptions, and retained messages are pre-allocated at compile time. No malloc and no fragmentation means a deterministic footprint. All limits (client count, buffer sizes, subscription count) are compile-time configurable.
Default static footprint is approximately 140 KB of RAM (8 clients, 32 subscriptions, 16 retained messages). Scale these down for smaller deployments.
Features
- MQTT v3.1.1 and v5.0 with full QoS 0, 1, and 2 support
- Topic wildcards: + single-level, # multi-level
- Retained messages with v5 message expiry (currently does not persist a broker restart)
- Last Will and Testament with v5 will delay interval
- Keep-alive monitoring and session persistence
- Username/password authentication with constant-time comparison
- TLS 1.2/1.3 and mutual TLS via wolfSSL
- Assigned Client IDs, User Properties, and Reason Codes (v5)
Each feature (retained messages, LWT, wildcards, auth, logging) can be independently disabled at compile time to reduce code size.
Non-Blocking Architecture
The broker uses a step function (MqttBroker_Step) that processes one loop iteration and returns immediately. This integrates naturally into bare-metal superloops, RTOS threads, or cooperative schedulers. A blocking MqttBroker_Run wrapper is also provided.
Getting Started
Build with Autotools or CMake:
./configure --enable-broker && make
Run:
./src/mqtt_broker -p 1883 ./src/mqtt_broker -p 8883 -t -c server-cert.pem -K server-key.pem # with TLS ./src/mqtt_broker -p 1883 -u myuser -P mypass # with auth
Embed in your application:
MqttBroker broker;
MqttBrokerNet net = {
.listen = my_listen, .accept = my_accept,
.read = my_read, .write = my_write, .close = my_close
};
MqttBroker_Init(&broker, &net);
MqttBroker_Start(&broker);
while (running) {
int rc = MqttBroker_Step(&broker);
if (rc == MQTT_CODE_CONTINUE) { /* idle */ }
}
MqttBroker_Free(&broker);
Part of the wolfSSL Ecosystem
The broker integrates with wolfSSL (TLS 1.3, FIPS 140-3), wolfIP (embedded TCP/IP), and the wolfMQTT client – giving you a complete, auditable MQTT stack from a single source.
Learn More
If interested in adding any features or have any questions/feedback please email us at facts@wolfssl.com or call us at +1 425 245 8247.
Download wolfSSL Now

