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.5.2 [Darwin 25.5.0]
Apple M5 Pro, 18 logical / 18 physical cores
.NET SDK 10.0.301, .NET 10.0.9, 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 | 17.3 ns | 0.81 | 88 B |
| Synapse | 21.4 ns | 1.00 | 72 B |
| MediatR | 27.7 ns | 1.30 | 200 B |
| Synapse (direct handler) | 6.8 ns | 0.32 | 72 B |
Send — request without response (void)
| Library | Mean | Ratio | Allocated |
|---|---|---|---|
| Synapse | 18.1 ns | 1.00 | 0 B |
| Mediator | 20.2 ns | 1.12 | 88 B |
| MediatR | 30.6 ns | 1.69 | 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 | 79.8 ns | 0.61 | 184 B |
| Synapse | 130.4 ns | 1.00 | 520 B |
| MediatR | 358.6 ns | 2.75 | 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.7 ns | 1.00 | 72 B |
| Mediator | 28.6 ns | 1.26 | 240 B |
| MediatR | 57.7 ns | 2.54 | 440 B |
Pipeline — request through 3 behaviors
| Library | Mean | Ratio | Allocated |
|---|---|---|---|
| Synapse | 26.2 ns | 1.00 | 72 B |
| Mediator | 53.4 ns | 2.04 | 496 B |
| MediatR | 89.7 ns | 3.43 | 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 (18.1 vs 20.2 ns) and allocates nothing.
- Publish — Mediator's generated fan-out wins; Synapse is ~2.75× 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/.