# Eclipse Paho MQTT C++: a modern C++ client that is really a wrapper around the Paho C library

> paho.mqtt.cpp gives C++17 applications an MQTT client with blocking and non-blocking APIs, but it is not a standalone implementation: it is a layer over the Paho C library, which must be built and installed separately or pulled in through a submodule. The project also carries a topic matching fix in v1.6.0 that closed an undefined behaviour path on empty topics.

**eclipse-paho/paho.mqtt.cpp** — An Eclipse Paho C++ client library for MQTT for Windows, Linux and MacOS.

- Repository: https://github.com/eclipse-paho/paho.mqtt.cpp
- Website: https://eclipse.org/paho
- Stars: 1,335 · Forks: 479
- Language: C++
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/eclipse-paho-paho-mqtt-cpp

## The dependency you cannot avoid: Paho C 1.3.16

The first thing to understand about paho.mqtt.cpp is that it is not a self-contained MQTT implementation. The README says the code requires the Paho C library by Ian Craggs and others, specifically version 1.3.16 or possibly later, and the project description calls it an Eclipse Paho C++ client library for memory-managed operating systems such as Linux, MacOS and Windows.

The C++ layer is a modern interface over that C core. The README describes the target as Modern C++ applications, C++17 and beyond, that connect to an MQTT broker, publish messages, subscribe to topics and receive messages from the broker. The point of the C++ library is the interface shape, not a new protocol engine, and the feature list reads like the C library's feature list with an idiomatic surface on top.

That has one big practical consequence. There are two libraries to build, install and link, and they must be compatible with each other. The README offers two ways to deal with that. You can build and install the Paho C library yourself, version 1.3.16 or greater, before building the C++ one, and in that case you will often need CMAKE_PREFIX_PATH to help the build system find where it landed. Or you can let the C++ build pull it in, using the CMake PAHO_WITH_MQTT_C option, which the README recommends because it guarantees a proper version of the C library is used and that it is built with compatible options.

Enabling PAHO_WITH_MQTT_C does more than fetch the dependency. The README says it passes the PAHO_WITH_SSL option through to the C library and also sets PAHO_HIGH_PERFORMANCE and PAHO_WITH_UNIX_SOCKETS for the C library. Those can be disabled in the CMake cache before building if you want different behaviour, which is the mechanism for the case where the bundled defaults do not suit your platform.

The submodule is the practical route, and the release notes confirm the version is being tracked deliberately. In v1.6.x the Paho C submodule was bumped to v1.3.16 and the directory name was updated to externals/paho.mqtt.c, and a minimum version for Paho C was set in the CMake file.

## The build, in the six commands the README gives

The README calls building both libraries together the quickest and easiest way to do it, and the sequence is short. You clone, check out the tag, initialise the submodule, configure CMake with the two options, and build and install:

```
$ git clone https://github.com/eclipse-paho/paho.mqtt.cpp
$ cd paho.mqtt.cpp
$ git co v1.6.0

$ git submodule update --init

$ cmake -Bbuild -H. -DPAHO_WITH_MQTT_C=ON -DPAHO_BUILD_EXAMPLES=ON
$ sudo cmake --build build/ --target install
```

Two details in that block matter. The git co v1.6.0 line pins the tag, so a clone of master gives you a moving target and the tag gives you a known one, and the submodule update --init line is what pulls in the Paho C sources, without which PAHO_WITH_MQTT_C has nothing to build. The README notes this assumes the build tools and dependencies, such as OpenSSL, have already been installed.

The toolchain requirements are stated precisely. As of v1.5 the library uses C++17 features and therefore requires a fully compliant C++17 compiler, and the named options are GCC v8 or later, clang v5 or later, or Visual Studio 2017 15.8 (MSVC 19.15) or later. CMake is the only supported build system, and the current supported minimum version is cmake v3.13.

On Debian based systems the package set for the base toolchain is:

```
$ sudo apt-get install build-essential gcc make cmake
```

If you are using secure sockets, and the README says you probably should if you are sending messages across a public network, you also need:

```
$ sudo apt-get install libssl-dev
```

The documentation build needs doxygen and optionally graphviz:

```
$ sudo apt-get install doxygen graphviz
```

Unit tests are built using Catch2, which you must download and install yourself, and the README says Catch2 versions v2.x and v3.x are currently supported.

## Eight CMake options, and the platform defaults that surprise people

CMake options are the whole configuration surface, and the README lists them with their defaults. The defaults are the interesting part, because they differ by platform in a way that is easy to miss.

PAHO_BUILD_SHARED defaults to TRUE on Unix style systems and FALSE on Win32. PAHO_BUILD_STATIC defaults to FALSE on Unix style systems and TRUE on Win32. PAHO_WITH_SSL defaults to TRUE on Unix and FALSE on Win32. So on Windows you get a static library without SSL support by default, and on Linux you get a shared library with it. The SSL default in particular is a security-relevant difference between platforms, and if you are on Windows you need to turn it on explicitly.

The remaining options have uniform defaults. PAHO_BUILD_DOCUMENTATION is FALSE and creates the HTML API documentation, requiring Doxygen. PAHO_BUILD_EXAMPLES is FALSE and controls the example programs. PAHO_BUILD_TESTS is FALSE and builds the unit tests, requiring Catch2. PAHO_BUILD_DEB_PACKAGE is FALSE and configures cpack to build a Debian or Ubuntu package. PAHO_WITH_MQTT_C is FALSE unless you set it.

All of the build and test options default to off, which is the right default for a library that is going to be consumed by something else, but it means a fresh clone produces no examples and no tests until you ask.

One of the release note items in v1.6.x is about packaging rather than code. The Debian .deb file was properly versioned, and the architecture was added to the .deb file name. For a project distributed to Debian and Ubuntu users, a .deb that cannot be told apart by version and architecture is a support burden, and the fix makes the package names distinguishable.

The repository layout shows the supporting material. There is a Doxyfile at the root for the API documentation, a CODING_STYLE.md and a .clang-format, a .editorconfig, a CHANGELOG.md, a CONTRIBUTING.md, a CODE_OF_CONDUCT.md and a SECURITY.md. The doc/ and examples/ directories hold the documentation and the sample programs, and there are helper scripts at the root: buildtst.sh, devenv.sh, fmt.sh, and a scripts/ directory.

## Topic matching bugs fixed in v1.6.0, and the one that could crash a client

The v1.6.x notes are specific enough to be worth reading closely, because they describe the kind of defect that is invisible until a broker or a filter combination hits it.

The topic matching fixes are the bulk of them. The topic_matcher and topic_filter functions were fixed to properly match a parent with a multi-level wildcard, which is the '#' wildcard. The topic_filter was slightly optimised to do a simple string comparison if the filter does not contain wildcards, which is a fast path for the common case of a literal filter. And undefined behaviour on empty topic matching was prevented.

That last one is the one to care about most. Undefined behaviour on an empty topic is the kind of bug that does not crash immediately, it corrupts something else later, and the fix is in a code path that any application receiving a message with an empty topic would take. A client that subscribed with a wildcard filter and received a malformed or empty topic from a broker could in principle have been affected, and the fix landing in a release is the kind of thing to check for when assessing a version.

The other fix in the list is a crash. There was a fixed post-reconnect crash in the sync client. Automatic reconnect is one of the library's headline features, and a crash on the path that runs after a reconnect, in the synchronous API, means a client that had been working could fail at exactly the moment the network got flaky, which is when you most need it to work.

The performance side of v1.6.x comes from the C library bump. The v1.6.x line is tested and builds around the latest Paho C v1.3.16, which the README says has a number of performance enhancements and reduces a number of latency issues in connecting and publishing, with significant performance increases in lower latency for connect and publish as a result of the bump.

The version history itself is a little unusual. The three recent releases are v1.6.0 on 2026-02-24, v1.5.2 on 2025-03-11 and v1.4.2 on 2025-05-17. The ordering of those dates is not monotonic, because v1.4.2 is a backport released after v1.5.2, which tells you the project maintains parallel release lines rather than only moving forward on one.

## What the library gives an application, and what the examples show

The feature list is where you find out what a client library is actually for. The library supports MQTT v3.1, v3.1.1 and v5. Its network transports are standard TCP, UNIX-domain sockets, secure sockets with SSL/TLS, and WebSockets, both secure and insecure, with proxy support.

The transports are the part that matters in practice. UNIX-domain sockets and WebSockets are how you connect a client to a broker that is not reachable over the public internet, and the WebSocket transport is what a browser based client or a cloud hosted broker requires. Proxy support is there for corporate networks.

On the reliability side, there is message persistence, which is user configurable, with a built-in file persistence and a user-defined key/value persistence described as easy to implement. Automatic reconnect and offline buffering are both listed, and offline buffering is the feature that decides whether a burst of messages sent while the link is down is lost. High Availability is listed as a feature as well.

Both API styles are present, blocking and non-blocking, which is the single biggest difference from the C library and the reason to use the C++ one at all. A blocking client reads as a sequence of calls, and a non-blocking one hands you a callback. Because the C++ layer is a wrapper, you get both without writing the state machine twice.

The examples directory shows the surface, and the file names are the best catalogue of what the library can do. There are sync_publish, sync_consume, sync_consume_v5 and sync_reconnect, and the async equivalents async_publish, async_publish_time, async_consume, async_consume_v5, async_message_consume, async_message_consume_v5 and async_subscribe. There is async_subscribe_v5, data_publish for retained messages, topic_publish, ssl_publish and ws_publish for the secure and WebSocket transports.

Then the higher level patterns. multithr_pub_sub exercises the library from several threads at once, pub_speed_test measures publish throughput, mqttpp_chat is a chat client, server_props_v5 covers the MQTT v5 server properties, and rpc_math_cli with rpc_math_srvr is a request and response pattern built on top of publish and subscribe. The rpc pair is worth noting, because request and response over MQTT is something everyone needs and almost nobody wants to write by hand.

The documentation is generated with Doxygen from a Doxyfile at the repository root, and the online API reference is served from the eclipse.org/paho project page.

## Eclipse project mechanics: the ECA, the develop branch, and the licence files

Contributing to this repository comes with two requirements that are worth reading before you open a pull request.

First, this is an official Eclipse project, so it is required that all contributors sign an Eclipse Contributor Agreement. Second, pull requests should be submitted against the develop branch and not master. And all commits should be signed. The README points to CONTRIBUTING.md for the full details.

The develop branch convention is a good signal about how the project is run, since it means master carries released code and the next version is assembled separately, which fits the parallel release lines seen in the version history.

The licence situation needs attention, and this is the one place where the README is silent enough that you should read the files yourself. The repository root carries a LICENSE file, a NOTICE file, and two licence directories named edl-v10 and epl-v20, plus notice.html and about.html. The presence of both the Eclipse Distribution License v1.0 and the Eclipse Public License v2.0 in one repository is the standard Eclipse dual licensing pattern, and the other two files are the notice and about documents that the distribution licence requires.

Since this project is hosted under the Eclipse Foundation and GitHub cannot classify the licence identifier, the terms in those root files are the only authoritative statement. That matters for commercial adoption, because the practical question is whether your distribution model and your patent and attribution obligations are compatible with the terms you will find there, and that is a question for your own legal review rather than something the README answers.

On maintenance, the repository is not archived and the last push was on 2026-06-04, while the most recent release is v1.6.0 from 2026-02-24. The CHANGELOG.md at the repository root is where the full list of updates for each release lives, and the project also has a public presence on Mastodon through the account of a maintainer and an Eclipse Paho mailing list for questions.

## Conclusion

Eclipse Paho MQTT C++ fits an embedded or backend C++ system that already accepts a two library dependency chain and wants MQTT v3.1, v3.1.1 and v5 with both blocking and callback based APIs, automatic reconnect and offline buffering. It is the wrong choice if you want a single self-contained library, since the Paho C library has to be built and installed first, and the wrong choice for a project that cannot take a copyleft or EPL licensed dependency. Before adopting, build with the PAHO_WITH_MQTT_C option and the submodule so the C library version matches, and read the LICENSE, NOTICE and edl-v10 and epl-v20 files at the repository root, since the terms are dual licensed and the README does not summarise them.

## FAQ

### What does Eclipse Paho MQTT C++ require to build?

The Paho C library version 1.3.16 or later, which you can build separately and locate with CMAKE_PREFIX_PATH, or build together with the C++ library using the CMake option PAHO_WITH_MQTT_C. You also need CMake v3.13 or newer and a fully compliant C++17 compiler, such as GCC v8, clang v5 or Visual Studio 2017 15.8.

### How do I build paho.mqtt.cpp and the bundled Paho C library together?

Clone the repository, check out the tag you want, run git submodule update --init, then configure with cmake -Bbuild -H. -DPAHO_WITH_MQTT_C=ON -DPAHO_BUILD_EXAMPLES=ON and build and install with sudo cmake --build build/ --target install.

### Which MQTT versions does the Paho C++ client support?

MQTT v3.1, v3.1.1 and v5. Network transports include standard TCP, UNIX-domain sockets, SSL/TLS secure sockets and WebSockets, both secure and insecure, with proxy support, and the library offers both blocking and non-blocking APIs.

### What changed in Paho MQTT C++ v1.6.0?

The Paho C submodule was bumped to v1.3.16 and moved to externals/paho.mqtt.c for lower connect and publish latency, topic_matcher and topic_filter were fixed to match a parent with the multi-level '#' wildcard, undefined behaviour on empty topic matching was prevented, a post-reconnect crash in the sync client was fixed, and the Debian package was versioned with the architecture added to its file name.

## Sources

- [eclipse-paho/paho.mqtt.cpp on GitHub](https://github.com/eclipse-paho/paho.mqtt.cpp)
- [Issues](https://github.com/eclipse-paho/paho.mqtt.cpp/issues)
- [Project website](https://eclipse.org/paho)
- [README](https://github.com/eclipse-paho/paho.mqtt.cpp/blob/master/README.md)
- [Releases](https://github.com/eclipse-paho/paho.mqtt.cpp/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/eclipse-paho-paho-mqtt-cpp
