# MQTTnet: a .NET MQTT client and broker in one library

> MQTTnet ships an MQTT client and a broker as NuGet packages for .NET, so a C# service can speak MQTT or host its own broker without a separate daemon. The trade-off is that you own the broker's persistence and scaling.

**dotnet/MQTTnet** — MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker). The implementation is based on the documentation from http://mqtt.org/.

- Repository: https://github.com/dotnet/MQTTnet
- Stars: 5,067 · Forks: 1,152
- Language: C#
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/dotnet-mqttnet

## What MQTTnet is for, and who ends up using it

MQTTnet is a .NET library that implements MQTT on both sides of the connection. The README describes it as providing "a MQTT client and a MQTT server (broker)" and supporting the protocol up to version 5. That combination is the reason to look at it: most MQTT libraries in the .NET ecosystem give you a client and expect you to point it at Mosquitto, HiveMQ or a cloud endpoint. MQTTnet lets the same package set act as the endpoint.

The people who get value from this are C# and .NET engineers building IoT gateways, telemetry collectors, or device simulators. If you are writing an ASP.NET Core service that already terminates WebSockets and now needs to accept MQTT over WebSockets on the same host, MQTTnet's server side is the piece that avoids running a second process. If you are writing a test suite that needs a broker to exist for the duration of a test run, an in-process broker is simpler than container orchestration. The README also notes compatibility with Microsoft Azure IoT Hub on the client side, which covers the case where the broker is somebody else's and you only need the client.

The library targets a wide range of runtimes. The README claims compatibility with "mostly any supported .NET Framework version and CPU architecture", and the repository topics include netframework, netcore, uwp and anycpu. That breadth matters if part of your fleet is still on .NET Framework. It also means the package surface is not narrow, so check which target framework your project resolves to before assuming a feature is present.

## How the client and broker are wired together

The architecture separates the MQTT protocol layer from the transport. The README lists "extensible communication channels (e.g. In-Memory, TCP, TCP+TLS, WS)" as a general feature. A channel is what carries bytes; the protocol layer above it does not care whether those bytes traverse a socket, a TLS stream, a WebSocket, or memory inside the same process. That is what makes an in-process client-and-broker test possible without opening a port.

On the client side there are two levels. The README mentions an included core LowLevelMqttClient "with low level functionality", and a ManagedMqttClient "which maintains the connection and subscriptions automatically". The difference is who handles reconnection and queuing. The managed client queues application messages and re-schedules them for higher QoS levels automatically, according to the README. The low-level client leaves that to you. Choosing the low-level client means writing your own reconnect loop and your own handling of messages that were in flight when the connection dropped. That is not a defect, but it is the decision most tutorials skip.

On the server side, the README lists a set of capabilities that are unusual for a library-embedded broker: a list of connected clients, simultaneous support for clients on different protocol versions, the ability to publish its own messages and receive every message without a loopback client, extensible client credential validation, and a custom message interceptor that can transform or extend every received application message. Subscription validation is also there: the broker can deny subscribing to certain topics depending on the requesting client. Those hooks are the reason to embed a broker rather than run one, because they put authorization and message transformation in the same process as your application logic.

## Installing MQTTnet and connecting a client

MQTTnet is distributed through NuGet. The README gives the Package Manager console command, and the package page is at nuget.org/packages/MQTTnet. From the .NET CLI the equivalent package id is the same, so a project reference looks like this:

```bash
dotnet add package MQTTnet
```

After the restore completes, the package appears in your project file and the MQTTnet namespaces become available. Note that the README documents the Package Manager console form (`Install-Package MQTTnet`) rather than the CLI form; the package id is the same, but if you are following the README literally you will be in Visual Studio.

The README points to four samples in the repository as the recommended starting points: connecting with a broker, subscribing to data, publishing data, and hosting your own broker. They live under Samples/Client and Samples/Server, with the client samples in files named Client_Connection_Samples.cs, Client_Subscribe_Samples.cs and Client_Publish_Samples.cs, and the server sample in Server_Simple_Samples.cs. The samples project is Samples/MQTTnet.Samples.csproj, so the fastest way to see working code is to open the solution and run that project.

For a server, the README's own description of the feature set is the checklist: credential validation, message interception, subscription validation, retained messages, and WebSockets via a separate NuGet package built on ASP.NET Core. The README does not reproduce the broker construction code inline; it directs you to Server_Simple_Samples.cs. If you need WebSocket support specifically, the README states it comes through a separate package rather than the core one, so plan for an additional dependency.

## Where MQTTnet stops and you start

The clearest limitation is stated in the README itself: retained messages are supported "including persisting via interface methods (own implementation required)". The library gives you the hook, not the storage. If your deployment restarts the broker and clients rely on retained messages being there when they reconnect, you are writing that persistence layer. Nothing in the repository layout suggests a bundled database or file-backed store for this.

The broker is also a library, not an operational product. There is no documented clustering, no documented bridge to another broker, and no documented admin interface. A standalone broker gives you those as configuration. If your requirement is a broker that survives a node failure or that federates with a broker in another network, MQTTnet's server side does not claim to solve it, and the README is silent on both topics. That silence is the answer.

The performance figure in the README needs reading carefully. It states roughly 150,000 messages per second, and the footnote says this was tested on a local machine with an Intel i7 8700K, with the MQTTnet client and server running in the same process over the TCP channel, using an app stored in /Tests/MQTTnet.TestApp.NetCore. That is a loopback measurement of the library's own throughput, not a number you can map onto a deployment where clients arrive over a network and the broker has to hold state for thousands of connections. Treat it as an upper bound on the protocol path, not a capacity plan.

One more boundary: TLS is supported for client and server, but the README explicitly excepts UWP servers. If you are targeting UWP as a broker host, TLS is off the table.

## How MQTTnet differs from Mosquitto and from a client-only library

Mosquitto is a standalone broker written in C, configured through a file and run as a service. MQTTnet is a library you link into a .NET process. The practical difference is where the extension points live. With Mosquitto, authorization and message transformation happen through plugins or configuration, and your application talks to the broker over the network. With MQTTnet, the README's extensible credential validation and message interceptor are C# interfaces you implement in the same process as your application code, and the broker can publish its own messages without a loopback client. If your authorization logic already lives in a .NET service, that removes a network hop and a second deployment artifact.

The cost is the operational surface. Mosquitto ships as a binary with a configuration file, and persistence of retained messages and queued messages is a broker concern rather than your application's. MQTTnet's retained-message persistence is explicitly your implementation. So the comparison is not which one is faster; it is whether you want the broker to be a service or a component.

The other comparison is against client-only .NET MQTT libraries. Those assume an external broker and focus on the client API. MQTTnet covers both sides and keeps a uniform API across protocol versions, per the README, which means the same call shapes work whether you negotiate MQTT 3.1.1 or 5. If you only ever need a client against a managed cloud broker, the server side of MQTTnet is weight you are not using, though the README states the library has no external dependencies, so the cost is package size rather than a dependency tree.

## Maintenance, licensing and what an upgrade costs

The repository is not archived, and the last push was on 2026-08-09, which is recent enough that the project should not be described as dormant. The release history shows v5.2.0 on 2026-07-01, v5.1.0 on 2026-02-04, and v5.0.1 on 2025-01-05. The spacing is worth noting: roughly five months between 5.1.0 and 5.2.0, and about seventeen months between 5.0.1 and 5.1.0. This is not a project that ships weekly. If your plan depends on a fix landing in a minor release within a month, that cadence is the constraint you are accepting.

The README also points to a MyGet feed for preview packages. That is where pre-release builds appear before they reach NuGet, and it is the channel to watch if you need a fix that has not shipped. It is not a stability guarantee.

The licence is MIT, per the repository and the badge in the README. MIT permits use in closed-source and commercial products, and it requires that the copyright notice and permission notice be included. The project is supported by the .NET Foundation and has adopted the Contributor Covenant code of conduct. None of this is legal advice; if your organization has a licence review process, the file to hand it is LICENSE at the repository root.

Upgrade cost is mostly a function of the major version. The jump from 5.0.1 to 5.1.0 came after a long gap, and the README describes a uniform API across protocol versions, which suggests the library's own API is where breaking changes would land rather than in MQTT semantics. The README does not document a migration guide or a rollback procedure, so pin the version in your project file and read the release notes for v5.2.0 before moving.

## Conclusion

Adopt MQTTnet when the MQTT endpoint has to live inside a .NET process: an ASP.NET Core service that already speaks WebSockets, a gateway that needs to publish and subscribe without a loopback client, or a test harness that needs a broker in-process. Do not adopt it as a drop-in replacement for a standalone broker in a cluster where you expect someone else to handle persistence, bridging and clustering; the README documents none of those. Before writing code, verify two things: that the NuGet feed serves the version you need, and whether you require retained-message persistence, because the README states that it is supported only through interface methods that you implement yourself.

## FAQ

### How do I connect to an MQTT server with MQTTnet?

Install the MQTTnet package from NuGet and use the client samples in the repository as the starting point; the README specifically recommends Samples/Client/Client_Connection_Samples.cs for connecting with a broker. The README also notes a ManagedMqttClient that maintains the connection and subscriptions automatically, which is the higher-level option if you do not want to write your own reconnect logic.

### How does MQTTnet compare with Mosquitto?

Mosquitto is a standalone broker; MQTTnet is a .NET library that provides both a client and a broker you embed in your own process. The README lists extension points such as extensible credential validation and a message interceptor, which are C# implementations rather than configuration, but retained-message persistence is left to you.

### What alternatives to MQTTnet exist for .NET?

The README does not name alternatives. What it does establish is the scope you would be comparing against: a client and a server in one package, MQTT up to version 5, no external dependencies, and compatibility with Azure IoT Hub on the client side.

### How does MQTTnet compare with m2mqtt?

The README does not mention m2mqtt, so no direct comparison is available from the project's own documentation. What the README does state is that MQTTnet provides both a client and a server, supports MQTT up to version 5, and carries no external dependencies.

### How does MQTTnet compare with HiveMQ?

The README does not discuss HiveMQ. It does describe MQTTnet's server side as a broker you host inside your own .NET process, with extension points for credential validation, message interception and subscription validation, rather than a separately deployed broker service.

## Sources

- [dotnet/MQTTnet on GitHub](https://github.com/dotnet/MQTTnet)
- [Issues](https://github.com/dotnet/MQTTnet/issues)
- [License: MIT](https://github.com/dotnet/MQTTnet/blob/master/LICENSE)
- [README](https://github.com/dotnet/MQTTnet/blob/master/README.md)
- [Releases](https://github.com/dotnet/MQTTnet/releases)

---

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