Skip to content

Paho Embedded - MQTT Client Library Encyclopedia

by Ian Craggs
8 min read

The Paho embedded client libraries arose out of the desire to allow the smallest microcontrollers to easily connect to MQTT servers. In this world, there are a large number of operating systems and network APIs, so it was important that the libraries be as portable as possible. With this in mind I decided, after some helpful discussions, that the attributes needed by the APIs were:

  • to use very limited and predictable resources: no dynamic memory allocation

  • not to rely on any particular libraries for networking, threading or memory management

  • ANSI standard C, or basic C++ for maximum portability

Overview of Paho Embedded MQTT Client Library

Paho Embedded MQTT Client
Language C++
License EPL and EDL
API Style Blocking

While I tried to make these APIs as helpful as possible, the constraints of portability and low, predictable resource use means that they are sometimes less helpful than other MQTT libraries. Note that I say “APIs”: there is more than one. The two that have been released in Paho so far are:

  1. MQTTPacket: The lowest level library in C, the base on which the other APIs are built. It simply deals with serialization and deserialization of MQTT packets. There are some helper functions for reading packets from and writing them to, the network. It will work just about anywhere a C compiler exists.

  2. MQTTClient: A C++ library first written for the mbed platform. It is written in the conventional language for mbed, C++. It still avoids dynamic memory allocations, and has replaceable classes for OS and network dependent functions. Use of the STL is also avoided. It is based on, and requires, MQTTPacket.

A C version of MQTTClient also exists, and an asynchronous API is planned along with other optional features. For the purpose of this blog, I’m going to confine myself to the MQTTClient API.

Features Supported by Paho Embedded MQTT Client Library

MQTT 3.1 Yes
MQTT 3.1.1 Yes
Automatic Reconnect No
Disk Persistence No

Advanced Features Supported by Paho Embedded MQTT Client Library

QoS 0 Yes
QoS 1 Yes
QoS 2 Yes
Authentication Yes
Throttling No
Offline Message Buffering No


Installation of Paho Embedded MQTT Client Library

Because of the variety of microcontroller environments, there is no one install mechanism. The simplest option is to clone the git repository - this contains build scripts for Linux. On mbed, you can import the library into your IDE from An Arduino package is available from the Arduino Libraries page.

Network and Timer Classes

First of all you need classes, which implement network and timer functionality needed by the API for the platform you are building your application on. Examples for Linux, mbed and Arduino are already available. It should be a simple matter to create your own for another environment. The timer class (which counts down, not up) needs to implement the following methods:

constructor(int ms)                  // timer value in milliseconds
bool expired()                       // has the timer expired?    
void countdown_ms(unsigned long ms)  // re/start the timer countdown, milliseconds
void countdown(int seconds)          // re/start the timer countdown, seconds
int left_ms()                        // return the number of milliseconds left before the countdown expires

and the network class the following:

int read(unsigned char* buffer, int len, int timeout)  
    // read len bytes from the network into buffer, within timeout milliseconds
    // return number of bytes read, or -1 for fail
int write(unsigned char* buffer, int len, int timeout)
    // write len bytes from buffer to the network, within timeout milliseconds
    // return number of bytes written, or -1 for fail

as a minimum.

Application Setup

Before including the header file, if you want to use QoS 2, you must set:


otherwise the QoS code is omitted to save resources. If you activate QoS 2, then there is another setting:


which is the maximum number of unprocessed, or “in flight” messages that the API can handle. Then we can include the header:


How to Connect Paho Embedded MQTT Client Library?

First of all you need to establish the network connection. This is not done within the library, for portability. The mbed example for this is:

IPStack ipstack = IPStack();    
const char* hostname = "";
int port = 1883;
int rc = ipstack.connect(hostname, port);

We create the client object by passing a network class instance to it:

MQTT::Client<IPStack, Countdown> client = MQTT::Client<IPStack, Countdown>(ipstack);

Note the class names - these are passed as template parameters. MQTT::Client also has two other optional parameters:

int MAX_MQTT_PACKET_SIZE = 100 // the maximum MQTT packet size
int MAX_MESSAGE_HANDLERS = 5   // the maximum number of subscription callbacks

which we have not used here. Now we can issue the MQTT connect:

MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
data.MQTTVersion = 3; // the default version is 4 (that is, 3.1.1)
data.clientID.cstring = (char*)"mbed-icraggs";
rc = client.connect(data);
if (rc != 0)
   printf("rc from MQTT connect is %d\n", rc);
   printf("MQTT connected\n");

Connect With LWT

MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
data.willFlag = 1;
data.clientID.cstring = (char*)"mbed-icraggs";
data.will.topicName.cstring = (char*)"will topic";
data.will.qos = 2;            // default 0
data.will.retained = 1;       // default 0
data.will.message.cstring = (char*)"will message";
rc = client.connect(data);

Connect With Username/Password

MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
data.willFlag = 1;
data.clientID.cstring = (char*)"mbed-icraggs";
data.username.cstring = (char*)"username";
data.password.cstring = (char*)"password";
rc = client.connect(data);

How to Publish MQTT Message Using Paho Embedded?

MQTT::Message message;

char buf[100];
sprintf(buf, "Hello World!  QoS 0 message from app version %f", version);
message.qos = MQTT::QOS0;
message.retained = false;  // set to true for retained
message.dup = false;
message.payload = (void*)buf;
message.payloadlen = strlen(buf)+1;
rc = client.publish(topic, message);

How to Subscribe to An MQTT Message Using Paho Embedded?

void messageArrived(MQTT::MessageData& md)
    MQTT::Message &message = md.message;

    printf("Message %d arrived: qos %d, retained %d, dup %d, packetid %d\n", 
    ++arrivedcount, message.qos, message.retained, message.dup,;
    printf("Payload %.*s\n", (int)message.payloadlen, (char*)message.payload);

const char* topic = "mbed-sample";
rc = client.subscribe(topic, MQTT::QOS2, messageArrived);   
if (rc != 0)
    printf("rc from MQTT subscribe is %d\n", rc);

Each subscription has its own callback, which receives messages on the subscribed topic.

How to Unsubscribe to An MQTT Message Using Paho Embedded?

const char* topic = "mbed-sample";
rc = client.unsubscribe(topic);
if (rc != 0)
   printf("rc from unsubscribe was %d\n", rc);

How to Disconnect?

rc = client.disconnect();
if (rc != 0)
    printf("rc from disconnect was %d\n", rc);

Similar to connect, the disconnect method just issues the MQTT disconnect. You must close the network connection explicitly.


To use TLS, you must implement a network class, which establishes the secured connection and then reads from and writes to, that secured connection. The main MQTTClient code does not contain any specific TLS code. An example of how to do this is described here.

An Example Application of Using Paho Embedded

Ian Craggs

Ian Craggs works for IBM, and has been involved with MQTT for more than 10 years. He wrote the IBM MQTT server Really Small Message Broker which became the inspiration for the Eclipse Mosquitto project. He contributed C client libraries to the Eclipse Paho project at its onset and is now the project leader.

Related content:

HiveMQ logo
Review HiveMQ on G2