Skip to main content

Performance Overview

Excalibur.Dispatch is designed for low-latency messaging with explicit performance profiles for local and transport paths.

Before You Start

Key Performance Metrics (Feb 19, 2026 Baseline)

Baseline source folder:

  • benchmarks/baselines/net10.0/dispatch-comparative-20260219/results/
MetricValueSource
Dispatch single command (MediatR harness)118.79 ns...MediatRComparisonBenchmarks-report-github.md
Dispatch single command (Wolverine in-process harness)70.31 ns...WolverineInProcessComparisonBenchmarks-report-github.md
Dispatch single command (MassTransit mediator harness)67.20 ns...MassTransitMediatorComparisonBenchmarks-report-github.md
Dispatch queued command end-to-end (remote route parity harness)1.317 us...TransportQueueParityComparisonBenchmarks-report-github.md
Dispatch ultra-local API (single command)47.12 ns...MediatRComparisonBenchmarks-report-github.md
Pre-routed local command106.0 ns...RoutingFirstParityBenchmarks-report-github.md

Comparison Snapshot

TrackStatus
MediatR in-process parityMediatR faster in current baseline
Wolverine in-process parityDispatch faster
MassTransit mediator in-process parityDispatch faster
Queued/bus end-to-end parityDispatch faster in current baseline

See Competitor Comparison for full tables and methodology notes.

Quick Wins

1. Use Ultra-Local for local hot paths

var result = await dispatcher.DispatchAsync(new CreateOrderAction(...), ct);

For explicit control, see Ultra-Local Dispatch.

2. Keep messages deterministic where possible

public record CreateOrderCommand(Guid OrderId, string CustomerId) : IDispatchAction;
public class CreateOrderHandler : IActionHandler<CreateOrderCommand> { }

3. Keep auto-freeze enabled

var host = builder.Build();
await host.RunAsync();

4. Prefer direct IMessageContext properties

context.ProcessingAttempts++;

Performance Guides

GuideDescription
Ultra-Local DispatchLowest-overhead local command/query path
Auto-FreezeAutomatic cache optimization
MessageContext Best PracticesHot-path optimization patterns
Competitor ComparisonTwo-track benchmarks vs MediatR/Wolverine/MassTransit

Memory Allocation Strategy

Dispatch reduces allocations through:

  1. Object pooling for MessageContext
  2. ArrayPool<T> on batch-style paths
  3. Lazy initialization for optional context state
  4. ValueTask-based local fast paths

Running Benchmarks

# Full matrix refresh
pwsh ./eng/run-benchmark-matrix.ps1 -NoRestore -NoBuild

# In-process parity track
pwsh ./eng/run-benchmark-matrix.ps1 -NoRestore -NoBuild -Classes MediatRComparisonBenchmarks,WolverineInProcessComparisonBenchmarks,MassTransitMediatorComparisonBenchmarks

# Queued/bus end-to-end parity track
pwsh ./eng/run-benchmark-matrix.ps1 -NoRestore -NoBuild -Classes TransportQueueParityComparisonBenchmarks

Results default to BenchmarkDotNet.Artifacts/results/.

See Also