Skip to content
Nuvyntra Labs

Documentation

Benchmark

Localhost publish and consume comparison of NuvexaMQ 0.1.0 and RabbitMQ 4.3.6 on one Mac, and how to repeat the NuvexaMQ run.

Overview

This is a localhost comparison of NuvexaMQ 0.1.0 and RabbitMQ 4.3.6 on one Mac. It is not a published multi-node benchmark. Both brokers ran the same client shape, one after the other, on 2 October 2026.

Machine

Apple M1 Pro, 8 CPU cores, 16 GB RAM. Both brokers were on this machine. Nothing else was publishing to the stream or queue under test.

Workload

SettingValue
Publisher connections8
Messages per publisher10,000
Timed publishes80,000
Warmup, not timed200 messages on one connection, before the clock starts
Payload128 bytes
Consumer connections8
In flight256 messages per consumer

Each publisher sends one message and waits for the broker to accept it before sending the next. The publish clock covers the 80,000 timed messages. The consume clock covers those messages plus the 200 warmup messages (80,200).

The runs did not overlap. NuvexaMQ was a Release build of the server on port 29761 with its own data directory. The desktop broker on port 5761 was not the process under test. RabbitMQ listened on port 5672.

Result

PublishConsume
NuvexaMQ 0.1.016,073 msg/s (4.98 s)65,923 msg/s (1.22 s)
RabbitMQ 4.3.69,475 msg/s (8.44 s)50,919 msg/s (1.58 s)

NuvexaMQ’s bench stream ended at offset 80,200, and the drain consumer finished with nothing pending.

RabbitMQ’s consume rate on this Mac moved between repeats. An earlier run of the same program reached 60,456 msg/s, and another reached 47,028 msg/s. The table uses the RabbitMQ run taken immediately beside the NuvexaMQ run.

What each side confirmed

NuvexaMQ published to stream bench (filter bench.>, one partition). A publish acknowledgement means the record was in a batch that fsync had returned for. On macOS that is libc fsync, the same durability RabbitMQ uses here: the write survives a process crash, and a power cut can still drop the last writes. Consumers fetch up to 256 messages and acknowledge that batch together.

RabbitMQ used one durable classic queue, nuvexa-bench. Messages were persistent. Each publisher enabled confirms and waited for a confirm on every message. Each consumer used manual acknowledgement and a prefetch of 256. Acknowledgements were not waited on one by one. The queue was deleted after the run.

Repeat the NuvexaMQ run

samples/Bench is the client used above. It leaves the bench stream in place.

dotnet run -c Release --project samples/Bench/Bench.csproj -- \
  --port=5761 --publishers=8 --each=10000 --size=128 --consumers=8
FlagDefaultMeaning
--host127.0.0.1Broker address
--port5761Data port
--publishers8Parallel publish connections
--each10000Messages on each publish connection
--size128Payload size in bytes
--consumers8Parallel consume connections. They share the durable consumer name drain.

Point --port at a broker whose data directory you can fill. The sample creates stream bench if it is missing and appends to it if it already exists. One connection is much slower than eight, because that connection waits alone for each fsync. More connections share the flush.

Repeat the RabbitMQ run

The RabbitMQ client is not in this repository. The measured run used RabbitMQ.Client 6.8.1 against 127.0.0.1:5672 as guest / guest, with the queue and confirm settings in the section above, and the same connection counts, message size, and message counts.

Discussion

Comment on NuvexaMQ. The thread lives on this component's GitHub repository (nuvyntralabs/NuvexaMQ). Sign in with GitHub — Giscus uses Discussions, Utterances uses Issues.