Benchmark
Benchmark lifecycle marks, runtime telemetry and HTTP response benchmark metadata.
Overview
Benchmark runtime lives under Observability\Benchmark. Benchmark holds current run state and BenchmarkRun captures marks, elapsed time and memory deltas.
Provider wiring
BenchmarkServiceProvider registers benchmark runtime services used by HTTP and CLI kernels.
$container->singleton(Benchmark::class, Benchmark::class);
$container->singleton(BenchmarkResponseInjector::class, BenchmarkResponseInjector::class);
Lifecycle marks
Benchmark marks are recorded during bootstrap, middleware and dispatch flow. Only marks listed below are part of the current runtime implementation.
$run->mark('start');
$run->mark('kernel_start');
$run->mark('config_loaded');
$run->mark('core_logger_ready');
$run->mark('framework_providers_registered');
$run->mark('app_providers_registered');
$run->mark('routes_registered'); // HTTP kernel
$run->mark('request_received');
$run->mark('middleware_enter');
$run->mark('benchmark_middleware_enter');
$run->mark('route_match_start');
$run->mark('route_matched');
$run->mark('controller_resolve_start');
$run->mark('controller_resolved');
$run->mark('controller_action_start');
$run->mark('controller_action_finished');
$run->mark('response_created');
$run->mark('response_ready');
$run->mark('finish');
HTTP benchmark flow
HTTP benchmark starts in Kernel::handle(), continues through Framework::run(), BenchmarkMiddleware, route dispatch and controller resolution. BenchmarkResponseInjector attaches benchmark metadata to the outgoing response.
$response = $response
->withHeader('X-Benchmark-Time-Ms', $elapsedMs)
->withHeader('X-Benchmark-Memory-Delta', (string) $memoryDeltaBytes)
->withHeader('X-Benchmark-Peak-Memory', (string) $peakBytes)
->withHeader('X-Benchmark-Peak-Allocated-Memory', (string) $peakAllocatedBytes);
CLI benchmark flow
CLI starts benchmark in CliKernel::handle() and records bootstrap marks as part of CLI command lifecycle. CLI-specific bootstrap also records providers_registered.
Benchmark logging
When benchmark logging is enabled in LoggingConfigDefinition, BenchmarkMiddleware writes a request.benchmark event through LogManager::benchmark().
$this->logs->benchmark()->info('request.benchmark', [
...$run->toArray(),
'status' => $status,
'elapsed_ms' => round($run->elapsedMs(), 3),
'memory_delta_bytes' => $run->memoryDeltaBytes(),
]);
Reading benchmark data
Benchmark data is available through response headers, optional HTML response comment (controlled by BenchmarkConfig::$injectHtmlComment) and benchmark log events. HTML comment injection is applied only for text/html responses.
Configuration
Benchmark HTML comment injection is configured in app/Config/Benchmark.yaml. Benchmark log channel settings live in app/Config/Logging.yaml. Both YAML documents are mapped into typed definitions and then resolved into runtime config DTOs by the existing framework config pipeline.
# app/Config/Benchmark.yaml
module: benchmark
config:
inject_html_comment:
$env: BENCHMARK_INJECT_HTML_COMMENT
type: bool
default: true
# app/Config/Logging.yaml
module: logging
config:
benchmark:
enabled:
$env: BENCHMARK_LOG_ENABLED
type: bool
default: true
path:
$env: BENCHMARK_LOG_FILE
type: string
default: benchmark.log
days:
$env: BENCHMARK_LOG_DAYS
type: int
default: 7