Skip to content

Benchmarks

All numbers come from BenchmarkDotNet with MemoryDiagnoser, on real hardware. No synthetic inflation.

Environment

PropertyValue
Runtime.NET 10.0.1, Arm64 RyuJIT AdvSIMD
OS / CPUmacOS, Apple M5
BenchmarkDotNetv0.14.0
MediatRv12.4.1
Mediantv1.0.0

Publish — notification fanout

Where Mediant wins decisively. MediatR allocates a NotificationHandlerExecutor wrapper plus a closure delegate per handler, per call. Mediant invokes handlers directly — zero wrapper allocation.

HandlersMediantMediatR v12SpeedMemory
124 ns / 88 B44 ns / 288 B46% faster3.3× less
1069 ns / 376 B184 ns / 1,656 B63% faster4.4× less
50276 ns / 1,656 B792 ns / 7,736 B65% faster4.7× less
100527 ns / 3,256 B1,521 ns / 15,336 B65% faster4.7× less

Send — command/query pipeline

The hot path: every request goes through Send(). Behaviors are scaled exponentially to show how each library handles pipeline depth.

BehaviorsMediantMediatR v12SpeedMemory
024 ns / 64 B24 ns / 128 B~equal2× less
159 ns / 288 B57 ns / 368 B~equal22% less
275 ns / 424 B70 ns / 512 B~equal17% less
4102 ns / 696 B100 ns / 800 B~equal13% less
8150 ns / 1,240 B159 ns / 1,376 B6% faster10% less
16262 ns / 2,328 B277 ns / 2,528 B5% faster8% less
32478 ns / 4,504 B507 ns / 4,832 B6% faster7% less

Speed is within noise through 4 behaviors; from 8 up Mediant pulls ahead, and the gap widens with depth. Memory is lower in every scenario.

Query — with a return value

ScenarioMediantMediatR v12SpeedMemory
Query returning Result<int>28 ns / 104 B28 ns / 200 B~equal1.9× less

Note that Mediant returns the richer Result<int> here, while MediatR returns a raw int.

Scorecard

CategoryBenchmarksMediant winsTieMediatR wins
Send (8+ behaviors)3300
Send (0–4 behaviors)4040
Query1010
Publish4400
Total12750

Mediant allocates less memory in all 12 benchmarks, and never loses on speed.

Load tests

18 load tests, part of a 300-test suite spanning unit, integration, load and E2E.

Concurrency and throughput

TestScaleResult
Concurrent Send10,000 simultaneousNo deadlocks, all succeed
Concurrent Send + behaviors50,000 simultaneousNo deadlocks, all succeed
Concurrent Query5,000 simultaneousAll succeed, correct results
Scoped DI (per request)10,000 scopesAll independent
Mixed operations10,000All complete cleanly

Memory and stability

TestScaleResult
Sequential memory leak100,000 requests< 10 MB growth
Sequential + behaviors500,000 requests< 20 MB growth
High-cardinality cache keys10,000 unique keys< 20 MB growth
Thread-pool exhaustion20,000 operationsPool not depleted

Resilience

TestScaleResult
Exceptions under load10,000 (33% failing)All complete, no leaks
Cancellation mid-flight5,000 + cancelNo hanging tasks
Re-entrant Send1,000 × depth 3No deadlocks
Parallel fanout5,000 × 10 handlers50,000 executions, all succeed
Streaming consumers100 × 1,000 itemsAll correct

Sustained latency (10 seconds): p50 < 1 ms, p95 < 5 ms, p99 < 10 ms, throughput > 10,000 req/sec.

Reproduce them

Terminal window
git clone https://github.com/omercelikdev/mediant.git
cd mediant
# BenchmarkDotNet comparison vs MediatR
dotnet run -c Release --project tests/Mediant.Benchmarks
# Load tests
dotnet test tests/Mediant.LoadTests