HiveMQ MQTT Client offers three API flavours over the same MQTT 5 engine
HiveMQ MQTT Client is an MQTT 5.0 and MQTT 3.1.1 compatible and feature-rich high-performance Java client library with different API flavours and backpressure support
At a glance
- What is it?
- The HiveMQ MQTT Client is a Java library for MQTT 5.0 and 3.1.1 that exposes the same client through reactive, asynchronous and blocking APIs, with backpressure, manual acknowledgement and a broad transport matrix. It fits a Java team that has to bridge MQTT with an existing concurrency model, and it does not fit a project that wants one small dependency on a broker SDK.
- Who is it for?
- HiveMQ MQTT Client fits a Java team that needs full MQTT 5 support, a choice of concurrency model, and explicit control over acknowledgement and flow control, and it does not fit a project that would rather use the broker vendor's own SDK for a single protocol version.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Java, 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
Four API flavours over one client, and the choice is the feature
The HiveMQ MQTT Client is described as an MQTT 5.0 and MQTT 3.1.1 compatible, feature-rich, high-performance Java client library with different API flavours and backpressure support. The API flavours are the distinguishing part.
There are three. The reactive flavour is Reactive Streams compatible, with RxJava and Reactor APIs available. The asynchronous API uses futures and callbacks. The blocking API is for quick start and testing. And you can switch flexibly between flavours and use them concurrently, with the flavours clearly separated but sharing a consistent API style.
That last point is the interesting design decision. The same client object, the same connection, the same subscriptions, and you consume them from whichever style fits the calling code. A team with a reactive core can pull MQTT messages into a Reactor pipeline; a team with a legacy service can block on a receive call without a thread pool of its own; a batch job can use the blocking API and be done.
The alternative, and the reason this library exists, is that most Java MQTT clients pick one style and force you into it. A blocking client in a reactive service means blocking a reactive thread. A reactive client in a legacy service means learning a whole new programming model for one integration. HiveMQ's position is that the transport and the protocol machinery are expensive to write and worth doing once, and the consumption style is cheap to vary.
The project is Apache-2.0 licensed, published to Maven Central as com.hivemq:hivemq-mqtt-client, and the last push was on 2026-10-15, after the v1.4.1 release of 2026-10-13, following v1.4.0 in August 2026 and v1.3.17 in July 2026.
Backpressure is implemented at three levels, which is where the difficulty is
Backpressure support is listed with three sub-items, and the differences between them matter more than the label.
First, QoS 1 and QoS 2. These are the delivery guarantees where the protocol itself defines acknowledgement flow, so the client has to mediate the acknowledgement rate to match what the consumer can absorb.
Second, QoS 0, where the client drops incoming messages if necessary. That is the honest answer for at-most-once delivery. A fire-and-forget subscription that the consumer cannot keep up with has to lose messages somewhere, and choosing to drop them in the client is better than buffering without bound until the process dies.
Third, and most interestingly, the client brings MQTT flow control and reactive pull backpressure together. MQTT 5 has a flow control mechanism at the protocol level, and reactive streams have a pull-based demand model, and the client reconciles the two. That reconciliation is the hard part: the broker's receive maximum and the consumer's demand signal are different concepts, and mapping one onto the other incorrectly produces either stalls or unbounded buffering.
Manual message acknowledgement is the fourth piece and it is more nuanced than the name suggests. You can selectively enable manual acknowledgement for specific streams. Messages emitted to multiple streams are acknowledged independently per stream, with the client aggregating the acknowledgements before sending the MQTT acknowledgements. And the order of manual acknowledgement does not matter, because the client automatically ensures the order of MQTT acknowledgements for full compatibility with the MQTT specification.
That last guarantee is the kind of detail that separates a client that understands the protocol from one that does not. A consumer can acknowledge out of order for its own convenience, and the wire protocol still sees a correctly ordered sequence.
The transport matrix is broad, and each option is a separate artifact
The transport list is unusually complete, and it is the part of the design that determines whether the client fits your network.
TCP is the baseline. SSL/TLS is supported for all TLS versions up to TLS 1.3, with TLS mutual authentication, TLS Server Name Indication, TLS Session Resumption, and default and customizable hostname verification. WebSocket and Secure WebSocket are supported, along with a proxy layer covering SOCKS4, SOCKS5 and HTTP CONNECT. The README states that all possible combinations are supported, so TLS over a SOCKS5 proxy over WebSocket is in scope.
What matters operationally is that these are not all in the core artifact. The optional features are separate modules: hivemq-mqtt-client-websocket, hivemq-mqtt-client-proxy and hivemq-mqtt-client-epoll, each with the reactor module as an additional dependency for the reactive API. The repository layout matches, with websocket/, proxy/, epoll/ and reactor/ directories alongside src/.
The epoll module is the one worth understanding. It is a Linux-specific transport, and it is the mechanism by which the library avoids the NIO selector path that a standard Java socket implementation would use. For a client with a very large number of connections, which is the normal shape of an MQTT deployment, that difference is the difference between a client that fits on one box and one that needs several.
The hostname verification point is also worth reading closely. Customizable hostname verification means you can relax it, and a client that lets you relax it is a client where a mistake is easy to make. Mutual authentication and SNI are the settings that matter most for a client connecting into a corporate or cloud MQTT endpoint with a hostname other than the broker's.
The lifecycle work is automatic and configurable
Several pieces of what MQTT clients usually get wrong are handled for you, and each is described as automatic and configurable.
Thread management is automatic and configurable, which is the piece most clients get wrong. A Java client that spawns a thread per connection or per subscription will exhaust a thread pool long before it exhausts sockets, and the whole reason to use a non-blocking client is to avoid that. Handing the thread management to the library, with the ability to tune it, is the difference between a client that works under load and one that does not.
Reconnect handling and message redelivery are automatic and configurable, so a dropped connection is recovered without the application writing retry logic. Resubscription if the session expired is the same idea, applied to the case where the broker has forgotten your subscriptions because the session was not persistent. That case is a classic source of silent data loss, where a client reconnects successfully and then publishes to a topic nobody is subscribed to.
Lifecycle listeners cover the events you need to react to: when connected, and when disconnected or the connection failed. The distinction between a clean disconnect and a failed connection attempt is useful, because they call for different handling, and a client that reports both as a generic disconnection forces you to poll connection state to work out which happened.
The MQTT 5 specific features are where the client goes beyond the basics. There is pluggable Enhanced Authentication support, which the README describes as an addition to the MQTT specification, server-triggered re-authentication. Automatic Topic Alias mapping saves bandwidth on topics that repeat, which matters on metered connections. And interceptors for QoS flows let you observe or modify the acknowledgement sequence.
Adding the dependency is one coordinate, and the compiler target matters
Java 8 or higher is required. That is stated up front and it shows up in the build configuration, which is worth checking before you commit to the library, because a project on an older source level needs a compiler change.
For Gradle, the dependency goes into your build.gradle or build.gradle.kts:
dependencies {
implementation("com.hivemq:hivemq-mqtt-client:1.4.1")
}For Maven, the same coordinate goes into the pom.xml:
<project>
...
<dependencies>
<dependency>
<groupId>com.hivemq</groupId>
<artifactId>hivemq-mqtt-client</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
...
</project>The README adds a note that you have to set the compiler version to 1.8 or higher, with the properties block given explicitly:
<project>
...
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
...
</project>The optional modules are declared the same way, and in the Gradle form they use the platform notation:
dependencies {
implementation(platform("com.hivemq:hivemq-mqtt-client-websocket:1.4.1"))
implementation(platform("com.hivemq:hivemq-mqtt-client-proxy:1.4.1"))
implementation(platform("com.hivemq:hivemq-mqtt-client-epoll:1.4.1"))
implementation("com.hivemq:hivemq-mqtt-client-reactor:1.4.1")
}That is the whole installation story. There is no configuration file, no broker to install, nothing to start before you connect.
Who uses it, and what that says about the code
The README lists organisations using the client, and the list is a reasonable proxy for what the library is tested against. BMW CarIT and its joynr project, openHAB, Eclipse Ditto, the Open Smart Grid Platform, CorreoMQTT, the HiveMQ Spring Boot Starter from Smartsquare, OpenMUC, and the Gaia SDK from leftshiftone.
That range of projects, from automotive to industrial integrations, is exactly where the transport matrix and the acknowledgement handling matter.
The documentation is at hivemq.github.io/hivemq-mqtt-client, with Javadoc published to javadoc.io, a community forum at community.hivemq.com, and contribution guidelines in CONTRIBUTING.md plus a RELEASE.md at the root. The build is Gradle with Kotlin DSL, build.gradle.kts and settings.gradle.kts, alongside a gradle.properties, a gradlew wrapper and a renovate.json5 for dependency updates. The epoll, proxy, reactor and websocket modules are separate Gradle subprojects, and the examples directory has its own build.gradle.kts.
The library is Apache-2.0 licensed, which is the permissive end of the scale and carries no copyleft obligation for a commercial application that links it.
Editorial conclusion
HiveMQ MQTT Client fits a Java team that needs full MQTT 5 support, a choice of concurrency model, and explicit control over acknowledgement and flow control, and it does not fit a project that would rather use the broker vendor's own SDK for a single protocol version. Before adopting it, decide which API flavour your codebase already uses, since the reactive, asynchronous and blocking styles are separate and mixing them in one component is where the complexity shows, and note that the optional transports are separate Maven artifacts, so WebSocket, proxy and epoll support each add a dependency to your build.
Frequently asked questions
Which MQTT versions does the HiveMQ MQTT Client support?
The library implements all MQTT 3.1.1 and MQTT 5.0 features, with the README linking to the OASIS specifications for both. MQTT 5 specific additions include pluggable Enhanced Authentication with server-triggered re-authentication, automatic Topic Alias mapping and interceptors for QoS flows.
What API styles does the HiveMQ MQTT Client offer?
There are three flavours: a reactive API that is Reactive Streams compatible with RxJava and Reactor APIs available, an asynchronous API using futures and callbacks, and a blocking API for quick start and testing. You can switch between flavours and use them concurrently, and the flavours are separated but share a consistent API style.
How does the HiveMQ MQTT Client handle backpressure?
Backpressure is supported for QoS 1 and QoS 2, for QoS 0 by dropping incoming messages if necessary, and by bringing MQTT flow control and reactive pull backpressure together. Manual acknowledgement can be enabled per stream, acknowledgements for messages emitted to multiple streams are aggregated per stream, and the client keeps the MQTT acknowledgement order correct regardless of the order you acknowledge in.
How do I add the HiveMQ MQTT Client to a Maven project?
Add the com.hivemq:hivemq-mqtt-client dependency with version 1.4.1 to your pom.xml, and set the compiler source and target to 1.8 or higher since Java 8 is the minimum. Optional transports such as WebSocket, proxy and epoll are separate artifacts under the same groupId.
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/hivemq-hivemq-mqtt-client)Was this useful?