Benchmarks are written with PHPBench and live under
benchmarks/. They are not part
of mago's checked [source] paths, this is harness/tooling code, not library source, so it isn't
held to the same lint/analyze conventions as src/.
Running the benchmarks
composer benchmark
This runs phpbench run --report=aggregate using
phpbench.json.dist.
What's measured
-
MiddlewarePipeBench: dispatches a command throughMessageBus->MiddlewarePipewith a single pass-through middleware ahead of the terminalMessageHandlerMiddleware. Handler resolution is stubbed with a static resolver so the number isolates the cost of pipeline traversal itself (queue cloning/dequeue perNextinvocation). -
MessageBusDispatchBench: the total cost of handling a command end-to-end through a container-backed setup (LaminasServiceManager), including realMessageHandlerResolvercontainer lookups, matching how the bus is actually wired in an application, at 1 and 5 pass-through middleware.
Latest results
Recorded on 2026-08-06, PHP 8.4.24 (Linux x86_64, WSL2), 1000 revolutions / 5 iterations per subject.
| Benchmark | Subject | Set | Mode (μs) | RStDev |
|---|---|---|---|---|
|
benchHandle |
1 middleware |
3.363319 |
±3.81% |
|
benchHandle |
1 middleware |
4.650117 |
±1.62% |
|
benchHandle |
5 middleware |
6.909352 |
±1.93% |
MessageBusDispatchBench rose by roughly 0.35-0.56μs from the previous baseline (4.300098μs /
6.345840μs) after MessageHandlerResolver::resolve() gained a command/query handler-type check
(rejecting a resolved handler that doesn't implement the expected CommandHandlerInterface/
QueryHandlerInterface). MiddlewarePipeBench, which never touches the resolver, stayed flat,
confirming the increase is attributable to that added validation rather than noise.
At 1 middleware, MessageBusDispatchBench (real PSR-11 container + config-driven wiring) costs
about 1.3μs more than the equivalent MiddlewarePipeBench case, that's the overhead
MessageHandlerResolver's container lookup and handler-type check add on top of pure pipeline
traversal. Going from 1 to 5 middleware in MessageBusDispatchBench adds roughly 0.6μs per
middleware, consistent with MiddlewarePipe cloning the internal SplQueue once per
Next::handle() call.
Re-run composer benchmark and update this table after any change likely to affect pipeline or
resolver performance.