Benchmarks
Synapse is built for low latency and low allocations on the hot path. This page compares it against two popular in-process mediators:
- MediatR — reflection-based, the de-facto standard.
- Mediator (martinothamar) — source-generated, MediatR-like API.
All three run the same scenarios from a single BenchmarkDotNet suite in benchmarks/SynapseBenchmark. Numbers are reproducible — see Running the benchmarks below.
Benchmarks measure dispatch overhead only — handlers are no-ops (a sum, or Task.CompletedTask). Real applications are dominated by handler work (I/O, DB), so these differences matter most in high-throughput, fan-out, or allocation-sensitive paths.
Environment
BenchmarkDotNet v0.15.8, macOS Tahoe 26.6 (25G72) [Darwin 25.6.0]
Apple M5 Pro, 18 logical / 18 physical cores
.NET SDK 10.0.302, .NET 10.0.10, Arm64 RyuJIT
Lifetimes: Synapse and MediatR use their defaults; Mediator is registered as Transient to mirror MediatR's transient handlers for an apples-to-apples DI cost. Mediator's recommended Singleton lifetime would lower its numbers further.
Results
Lower is better. Ratio is relative to Synapse (baseline 1.00); Alloc is bytes allocated per operation.
Send — request with response
| Library | Mean | Ratio | Allocated |
|---|---|---|---|
| Mediator | 18.6 ns | 0.88 | 88 B |
| Synapse | 21.2 ns | 1.00 | 72 B |
| MediatR | 28.4 ns | 1.34 | 200 B |
| Synapse (direct handler) | 7.1 ns | 0.33 | 72 B |
Send — request without response (void)
| Library | Mean | Ratio | Allocated |
|---|---|---|---|
| Synapse | 17.6 ns | 1.00 | 0 B |
| Mediator | 22.4 ns | 1.27 | 88 B |
| MediatR | 30.2 ns | 1.71 | 128 B |
| Synapse (direct handler) | 3.6 ns | 0.20 | 0 B |
Synapse allocates zero bytes dispatching a void request.
Publish — one event, 5 handlers
| Library | Mean | Ratio | Allocated |
|---|---|---|---|
| Mediator | 74.2 ns | 0.57 | 184 B |
| Synapse | 130.6 ns | 1.00 | 520 B |
| MediatR | 357.1 ns | 2.74 | 2088 B |
Mediator's source-generated fan-out leads here; both beat MediatR by a wide margin.
Pipeline — request through 1 behavior
| Library | Mean | Ratio | Allocated |
|---|---|---|---|
| Synapse | 22.0 ns | 1.00 | 72 B |
| Mediator | 29.4 ns | 1.34 | 240 B |
| MediatR | 58.6 ns | 2.66 | 440 B |
Pipeline — request through 3 behaviors
| Library | Mean | Ratio | Allocated |
|---|---|---|---|
| Synapse | 26.3 ns | 1.00 | 72 B |
| Mediator | 51.9 ns | 1.97 | 496 B |
| MediatR | 89.3 ns | 3.40 | 728 B |
Synapse's pipeline allocation stays flat at 72 B regardless of behavior count, thanks to its cached, pre-composed delegate chain — competitors grow per added behavior.
Takeaways
- Pipelines — Synapse is fastest and flat-allocating; the gap widens as behaviors stack.
- Send (response) — Mediator edges ahead on raw speed; Synapse allocates less.
- Send (void) — Synapse beats Mediator (17.6 vs 22.4 ns) and allocates nothing.
- Publish — Mediator's generated fan-out wins; Synapse is ~2.74× faster than MediatR.
- All three vastly outperform reflection-based MediatR on both time and allocations.
Pick based on your workload: pipeline-heavy / allocation-sensitive favors Synapse; raw publish throughput favors Mediator.
Running the benchmarks
cd benchmarks/SynapseBenchmark
dotnet run -c Release # full suite, all libraries
dotnet run -c Release -- --filter '*Pipeline*' # one category
The suite lives in a single class, SynapseVsMediatorsBenchmarks. Results land in BenchmarkDotNet.Artifacts/results/.