paho-mqtt: the Eclipse Paho MQTT client for Rust
An Eclipse Paho Rust client library for MQTT for Windows, Linux and MacOS.
At a glance
- What is it?
- paho-mqtt is a safe Rust wrapper around the Eclipse Paho C library, exposing MQTT 5, 3.1.1 and 3.1 over TCP, TLS, WebSockets and Unix sockets, with three API styles including a runtime-agnostic async one. The installation story is a C library, and the notes are candid about what that costs you.
- Who is it for?
- paho-mqtt suits a Rust project that needs the Paho implementation specifically, for instance because an existing broker deployment or an enterprise agreement points at it, and the wrapper exposes the whole C feature set rather than a reduced subset, including the persistence and high availability options that pure Rust clients often leave out.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A safe wrapper around a C library
paho-mqtt is the Eclipse Paho MQTT Rust client library for memory-managed operating systems, meaning Linux and Posix, Mac and Windows, and the project is explicit about what it is: a safe wrapper around the Paho C library.
That single sentence tells you what to expect. The Rust crate is the safe layer, the protocol implementation, the TLS handling and the persistence all live in the C library, and the wrapper exists to make that usable from Rust with a memory-safe interface. The C library itself comes from a git submodule under the paho-mqtt-sys crate, which is the same arrangement other Rust projects use for a vendored C dependency.
The upshot for a user is that installing this crate is not the same as installing a pure Rust crate. By default the build attempts to compile the Paho C library for your target using pre-generated bindings, and it enables secure socket support against the system OpenSSL. That default behaviour requires a C compiler and CMake on the machine, and the notes give the Debian and Ubuntu packages for that:
$ sudo apt install libssl-dev build-essential cmakeThe library itself is the official one, with the manifest naming the Eclipse Paho organisation, and the version of the crate is 0.14.0 with edition 2021 and a minimum Rust version of 1.75.0.
The C feature set, exposed rather than trimmed
The feature list is described as everything available in the C library, which is the right approach for a wrapper and makes the library's capability obvious.
On the protocol side it supports MQTT v5, 3.1.1 and 3.1, and all three quality of service levels. The transports are standard TCP, Unix domain sockets on Unix only, SSL and TLS with optional ALPN protocols, and WebSockets in both secure and insecure forms, with optional proxy support. Last Will and Testament is there, which is what lets a broker infer that a client has died ungracefully.
The reliability options are the part that distinguishes this from a minimal client. There is message persistence, either built in as a file or in memory, or user defined with your own key and value store, and the documentation mentions an example for Redis. There is automatic reconnect, offline buffering so that messages published while disconnected are not lost, and high availability.
Three API styles are offered over the same core: an async and await API built on Rust futures and streams, a traditional asynchronous token and wait API, and a synchronous blocking API. It matters for anyone who does not want to adopt an async runtime at all.
The legacy token API is still underneath
The notes on async runtimes are the most interesting part of the documentation, because they explain a design that would otherwise look strange.
The library predates Rust's async and await by several years, and it was originally written with a legacy asynchronous API in which the calling function started an I/O operation without blocking for it to complete. Instead, the I/O functions returned a Token object that could be used to monitor progress or to block the caller until the operation finished. Internally, the Token uses a condition variable to signal completion and fill in the result, and the operation and the signalling are performed by a pair of internal threads that run the operation and signal the condition variable.
To make that compatible with modern Rust, the Token simply implemented the standard Future trait. The consequences are spelled out and they are worth knowing. I/O operations return a plain Future that any runtime can poll. Stream-style input uses a channel implementation that is runtime agnostic. And, unlike most futures, the operations are started as soon as the function is called, so they do not need an await to start; awaiting the token pauses the task until the operation completes. The legacy API still works underneath, so you can use async style operations with no async runtime at all, using the blocking wait functions on the token instead.
The library is agnostic to async runtimes and does not use a runtime for internal operations, and it is tested against tokio and smol. It was working against async-std too, but since that project is no longer maintained, it is no longer tested with it.
The build is where the real decisions are
The build features are the part of the configuration that changes what gets compiled, and the manifest lists them:
[features]
default = ["bundled", "ssl"]
bundled = ["paho-mqtt-sys/bundled"]
build_bindgen = ["paho-mqtt-sys/build_bindgen"]
ssl = ["paho-mqtt-sys/ssl"]
vendored-ssl = ["paho-mqtt-sys/vendored-ssl"]The bundled feature builds the Paho C library contained in the git submodule under the sys crate, which the notes compare to the vendored feature in other Rust projects. The ssl feature turns on secure sockets and secure WebSocket connections. The vendored-ssl feature builds OpenSSL as well, passing the vendored option through to the OpenSSL sys crate, and it needs the target C compiler plus Perl and make. The tokio feature is listed too, but it only builds some of the tokio examples, since the library is fully compatible with tokio without it.
There is one more mechanism worth understanding. The default build tries to speed things up by using pre-generated C bindings for the recommended Paho C library, and there are bindings for common build targets, with a fallback to a default for the target word size, 32 bit or 64 bit, when a specific target is not found. That fallback is why the notes give a specific instruction for a bad day: if you experience segfaults or other hard crashes, the first thing to try is the build_bindgen feature, which regenerates the bindings for your target. If that does not fix it, the notes ask you to file an issue.
The version numbers in the notes do not line up
There is a small inconsistency in the project documentation that anyone pinning versions should resolve for themselves. The features section states that the crate requires Paho C v1.3.16, or possibly later. The section on what is new in v0.14 says that v0.14.0 now wraps Paho C v0.3.16, and then, in the bullet list below it, says that support for Paho C v1.3.16 was added, with improved performance and lower latency for connect and publish operations.
So the same release is named with two different version strings in adjacent paragraphs, and the note about it being mainly concerned with internal performance improvements, with a noticeable decrease in latency for a number of operations for many applications, attaches to the 0.3.16 spelling.
There is a related mismatch in the crate versions. The manifest depends on the sys crate at version 0.11 by path, while the published release list shows a sys crate release at 0.10.3. None of this is a sign of anything broken, and the C library in question is a mature and slow moving dependency, but it does mean that the version story in the notes needs cross-checking against the manifest and the C library's own release notes before you pin anything.
What v0.14 added
The changes in the current release are worth listing, because they describe what the wrapper looks like now rather than what it is.
The headline is the new Paho C version, which the notes say was mainly concerned with internal performance improvements, and for many applications brings a noticeable decrease in latency across a number of operations, with the connect and publish paths called out specifically.
The second addition is synchronous and asynchronous event streams. All events from the client flow through the stream, and the list is given: Connect, Connection Lost, Disconnected and Incoming Message. That is a substantial ergonomic change, because previously a consumer had to attach a callback per event type, and now a single stream carries all of them, which is the shape a Rust program wants.
The rest is smaller but useful. Some tokio examples were added, and the MQTT v5 error handling was fixed up to properly report reason code errors, which is one of those changes that matters more than it sounds for anyone debugging a rejected publish. The full list of updates and fixes is in the changelog file, and the crate version is 0.14.0 with the sys crate alongside it.
Licence, examples and the shape of the project
The manifest declares the Eclipse Public License 2.0, and the repository root carries the licence files in the shape the Eclipse Foundation uses, with an edl-v10 directory, an epl-v20 directory, a notice file and an about file. The project is also a good citizen in the ways that matter for a foundation project, with a code of conduct, a contributing guide, a security policy and a changelog.
The examples are the clearest statement of the library's scope, and there are a lot of them: separate examples for async publish, async publish with timing, async subscribe, async subscribe on version 5, dynamic subscribe, event subscribe on version 5, the legacy async publish and subscribe, an RPC math client and server pair, SSL publish, synchronous consume and publish, the two tokio examples, topic alias publish, topic publish and a WebSocket publish. The two RPC examples are the ones worth a look, because an RPC pattern over MQTT is where the choice of client starts to matter.
The build scripts are there too, with a build and test shell script and a development environment script, and the last push to the repository was on 2026-04-03, a few days after the v0.14.0 release on 2026-03-26.
Editorial conclusion
paho-mqtt suits a Rust project that needs the Paho implementation specifically, for instance because an existing broker deployment or an enterprise agreement points at it, and the wrapper exposes the whole C feature set rather than a reduced subset, including the persistence and high availability options that pure Rust clients often leave out. It is the wrong choice if you want a dependency-free crate, because the default build compiles the Paho C library and needs CMake and a C compiler, and it is the wrong choice if your target is one of the less common platforms, since the pre-generated bindings cover the common targets and fall back to a word-size default otherwise. Before you adopt it, install the build prerequisites and keep the build_bindgen feature in mind as the first thing to try if you hit a segfault, and read the C library version yourself, because the notes mention two different version numbers for what appears to be the same release. The manifest declares the Eclipse Public License 2.0, and the current release is v0.14.0 from 2026-03-26.
Frequently asked questions
How do I add paho-mqtt to a Cargo project?
Add paho-mqtt = "0.14" to the dependencies. The default features bundled and ssl compile the Paho C library and enable secure sockets, which needs a C compiler and CMake, and on an Ubuntu or Debian system the notes suggest installing libssl-dev, build-essential and cmake.
Does paho-mqtt work with any async runtime?
Yes. The library is agnostic to async runtimes and does not use one for its internal operations, and it is tested against tokio and smol. It used to work with async-std, but that project is no longer maintained so it is no longer tested with it.
What is the build_bindgen feature for?
The default build uses pre-generated C bindings for common targets and falls back to one for the target word size. The project notes say that if you hit segfaults or other hard crashes, the first thing to try is the build_bindgen feature, which regenerates the bindings for your target, and to file an issue if that does not help.
Which MQTT protocol versions does paho-mqtt support?
MQTT v5, 3.1.1 and 3.1, across standard TCP, Unix domain sockets on Unix, SSL and TLS with optional ALPN, and WebSockets in secure and insecure forms with optional proxies. All three quality of service levels and Last Will and Testament are supported.
What persistence and reliability options does paho-mqtt offer?
Message persistence built in as a file or in memory, or user defined with your own key and value store, with an example for Redis. There is also automatic reconnect, offline buffering, high availability, and three API styles including a synchronous blocking one.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/eclipse-paho-paho-mqtt-rust)Was this useful?