Skip to main content

Competitor Comparison

This page documents comparative benchmark baselines for Excalibur.Dispatch using two explicit tracks:

  1. In-process parity (raw handler-dispatch style)
  2. Queued/bus semantics (publish/send + consumer flow)

Baseline Artifacts

  • Baseline folder: benchmarks/baselines/net10.0/dispatch-comparative-20260219/results/
  • Runtime: .NET 10.0.3
  • Tooling: BenchmarkDotNet v0.15.4
  • Machine: Intel Core i9-14900K, Windows 11 (10.0.26200.7840)
Scope

These are microbenchmarks for framework overhead and path cost. They are not end-to-end production latency claims.

Executive Summary

TrackSummary
In-process parity (MediatR)MediatR is faster in current baseline
In-process parity (Wolverine InvokeAsync)Dispatch is faster
In-process parity (MassTransit Mediator)Dispatch is faster
Queued/bus end-to-end parity (Dispatch remote route / Wolverine SendAsync / MassTransit bus)Dispatch is faster in current baseline

Track A: In-Process Parity

Dispatch vs MediatR

Source: benchmarks/baselines/net10.0/dispatch-comparative-20260219/results/Excalibur.Dispatch.Benchmarks.Comparative.MediatRComparisonBenchmarks-report-github.md

ScenarioDispatchMediatRRelative Result
Single command handler118.79 ns40.92 nsMediatR ~2.9x faster
Single command strict direct-local116.29 ns40.92 nsMediatR ~2.8x faster
Single command ultra-local API47.12 ns40.92 nsMediatR ~1.2x faster
Notification to 3 handlers154.47 ns96.10 nsMediatR ~1.6x faster
Query with return value126.63 ns49.29 nsMediatR ~2.6x faster
Query ultra-local API66.94 ns49.29 nsMediatR ~1.4x faster
10 concurrent commands1,244.58 ns497.81 nsMediatR ~2.5x faster
100 concurrent commands12,107.20 ns4,797.88 nsMediatR ~2.5x faster

Dispatch vs Wolverine (InvokeAsync parity)

Source: benchmarks/baselines/net10.0/dispatch-comparative-20260219/results/Excalibur.Dispatch.Benchmarks.Comparative.WolverineInProcessComparisonBenchmarks-report-github.md

ScenarioDispatchWolverine (Invoke/local)Relative Result
Single command70.31 ns193.14 nsDispatch ~2.7x faster
Notification to 2 handlers75.95 ns4,138.96 nsDispatch ~54.5x faster
Query with return97.43 ns259.53 nsDispatch ~2.7x faster
10 concurrent commands747.27 ns1,985.19 nsDispatch ~2.7x faster
100 concurrent commands7,033.04 ns19,976.37 nsDispatch ~2.8x faster

Dispatch vs MassTransit Mediator (in-process)

Source: benchmarks/baselines/net10.0/dispatch-comparative-20260219/results/Excalibur.Dispatch.Benchmarks.Comparative.MassTransitMediatorComparisonBenchmarks-report-github.md

ScenarioDispatchMassTransit MediatorRelative Result
Single command67.20 ns1,185.70 nsDispatch ~17.7x faster
Notification to 2 consumers83.36 ns1,705.15 nsDispatch ~20.4x faster
Query with return95.19 ns18,771.04 nsDispatch ~197.2x faster
10 concurrent commands779.68 ns11,924.61 nsDispatch ~15.3x faster
100 concurrent commands7,037.86 ns120,396.41 nsDispatch ~17.1x faster

Track B: Queued/Bus End-to-End Parity

Dispatch vs Wolverine vs MassTransit (queued end-to-end parity)

Source: benchmarks/baselines/net10.0/dispatch-comparative-20260219/results/Excalibur.Dispatch.Benchmarks.Comparative.TransportQueueParityComparisonBenchmarks-report-github.md

ScenarioDispatch (remote route)WolverineMassTransitRelative Result
Queued command end-to-end1.317 us4.005 us22.655 usDispatch ~3.0x faster than Wolverine, ~17.2x faster than MassTransit
Queued event fan-out end-to-end1.362 us3.943 us23.184 usDispatch ~2.9x faster than Wolverine, ~17.0x faster than MassTransit
Queued commands end-to-end (10 concurrent)7.132 us39.655 us147.692 usDispatch ~5.6x faster than Wolverine, ~20.7x faster than MassTransit
Interpretation Guardrail

Use Track A for closest in-process handler overhead parity. Use Track B when comparing queued/bus completion semantics.

Routing-First Local + Hybrid Parity

Source: benchmarks/baselines/net10.0/dispatch-comparative-20260219/results/Excalibur.Dispatch.Benchmarks.Comparative.RoutingFirstParityBenchmarks-report-github.md

ScenarioMeanRelative to local command
Dispatch: pre-routed local command106.0 nsbaseline
Dispatch: pre-routed local query141.3 ns+33.3%
Dispatch: pre-routed remote event (AWS SQS)183.3 ns+72.9%
Dispatch: pre-routed remote event (Azure Service Bus)191.8 ns+81.0%
Dispatch: pre-routed remote event (Kafka)189.1 ns+78.4%
Dispatch: pre-routed remote event (RabbitMQ)184.1 ns+73.7%
Dispatch: pre-routed Kafka observability profile321.2 ns+203.0%
Dispatch: pre-routed RabbitMQ observability profile321.4 ns+203.2%

Running These Comparisons

# Build once
dotnet build benchmarks/Excalibur.Dispatch.Benchmarks/Excalibur.Dispatch.Benchmarks.csproj -c Release --nologo -v minimal

# Track A (in-process parity)
pwsh ./eng/run-benchmark-matrix.ps1 -NoBuild -NoRestore -Classes MediatRComparisonBenchmarks,WolverineInProcessComparisonBenchmarks,MassTransitMediatorComparisonBenchmarks

# Track B (queued/bus end-to-end parity)
pwsh ./eng/run-benchmark-matrix.ps1 -NoBuild -NoRestore -Classes TransportQueueParityComparisonBenchmarks

Results are written to BenchmarkDotNet.Artifacts/results/ unless -ArtifactsPath is provided.