TurboMqtt Performance

February 22, 2026 · View on GitHub

v1.0 Benchmark Update

Updated for v1.0 on Linux Ubuntu 24.04, .NET 10.0, BenchmarkDotNet v0.15.8 (i9-9900K). Original Windows/.NET 8 results are archived below for historical reference.


Current Benchmarks (v1.0)

MQTT 3.1.1 Results

For detailed results including raw per-launch data, see performance/mqtt311-benchmarks.md.

QoSLevelPayloadSizeBytesMeanStdDevReq/sec
AtMostOnce10 B3.313 μs0.446 μs301,798
AtMostOnce1 KB3.220 μs1.276 μs310,516
AtMostOnce2 KB3.731 μs1.424 μs268,033
AtLeastOnce10 B3.878 μs1.875 μs257,854
AtLeastOnce1 KB3.904 μs0.996 μs256,154
AtLeastOnce2 KB3.544 μs1.084 μs282,199
ExactlyOnce10 B8.488 μs1.942 μs117,816
ExactlyOnce1 KB10.964 μs4.984 μs91,209
ExactlyOnce2 KB9.971 μs3.272 μs100,289
ExactlyOnce8 KB13.513 μs3.425 μs74,005

MQTT 5.0 Results

For detailed results, see performance/mqtt5-benchmarks.md.

QoSLevelPayloadSizeBytesMeanStdDevReq/sec
AtMostOnce10 B3.243 μs0.460 μs308,333
AtMostOnce1 KB3.175 μs1.073 μs314,928
AtLeastOnce10 B3.810 μs1.262 μs262,493
AtLeastOnce1 KB3.866 μs0.998 μs258,697
ExactlyOnce10 B8.862 μs1.830 μs112,846
ExactlyOnce1 KB9.694 μs1.771 μs103,161

MQTT 5.0 vs 3.1.1 Comparison

QoSLevelPayloadSizeBytesMQTT 3.1.1 (req/s)MQTT 5.0 (req/s)Delta
AtMostOnce10 B301,798308,333+2.2% ✅
AtMostOnce1 KB310,516314,928+1.4% ✅
AtLeastOnce10 B257,854262,493+1.8% ✅
AtLeastOnce1 KB256,154258,697+1.0% ✅

Verdict: no throughput regression. MQTT 5.0 shows slight performance improvements despite larger CONNECT/CONNACK frames and expanded property sets. The encoding/decoding overhead is negligible in the steady-state publish/subscribe path.


Benchmark Reproduction

To reproduce these benchmarks locally:

# Run all benchmarks
dotnet run -c Release --project benchmarks/TurboMqtt.Benchmarks

# Run only MQTT 3.1.1 end-to-end benchmarks
dotnet run -c Release --project benchmarks/TurboMqtt.Benchmarks -- --filter '*Mqtt311EndToEndTcp*'

# Run only MQTT 5.0 end-to-end benchmarks
dotnet run -c Release --project benchmarks/TurboMqtt.Benchmarks -- --filter '*Mqtt5EndToEndTcp*'

See benchmarks/README.md for detailed reproduction instructions.


Benchmark Design

Why design the benchmark this way?

We designed the benchmark to include everything in order to make it git clone + dotnet run -c Release runnable right out of the box. That's the standard for best developer experience, but that means making some comrpomises on accuracy.

Why the 10b message size?

We stuck with a relatively low message size because doing anything larger is mostly a matter of scaling Socket buffer sizes, and when we perform end-to-end benchmarking with real brokers like EMQX larger message sizes create memory pressure + availability problems for the broker itself. You can run these yourselves at larger sizes.

But the TL;DR; is: big messages are largely I/O bound problem - the whole purpose of TurboMqtt is make sure your publishing / receive message processing rates aren't CPU bound. Smaller message sizes make that easier to observe.

Data with Real Brokers

What sort of performance can you expect from real brokers?

TurboMqtt reading messages off of EMQX via MQTT 3.1.1

Using some of our application-specific stress tests, we've observed processing rates of ~70k msg/s (as fast as the stress testers could go against a single EMQX instance) running on QualityOfService.AtLeastOnce (QoS=1) - which is significantly faster than our benchmark data (see, we told you!)

Testing with larger packet sizes, such as 8kb packets, we've observed rates of around 35k msg/s, which translates to roughly 280 mb/s with a single client receiving messages. At those sizes you'll start to run into problems with your message broker long before TurboMqtt has any problems.