Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-26.2.0 | composer require openswoole/core:26.2.0
Since: OpenSwoole v26.2.0
OpenSwoole 26.2.0 introduces real-time event loop lag monitoring via $server->stats(). These metrics help you detect blocking operations that stall the event loop, such as synchronous file I/O, CPU-intensive computations, or unhookable blocking calls.
| Metric | Description |
|---|---|
event_loop_lag_ms | Current event loop lag in milliseconds |
event_loop_lag_max_ms | Maximum event loop lag observed since server start |
event_loop_lag_avg_ms | Average event loop lag |
These metrics are available per:
<?php
use OpenSwoole\Http\Server;
use OpenSwoole\Http\Request;
use OpenSwoole\Http\Response;
$server = new Server("0.0.0.0", 9501);
$server->set([
'worker_num' => 4,
]);
$server->on("request", function (Request $request, Response $response) use ($server) {
if ($request->server['request_uri'] === '/metrics') {
$stats = $server->stats();
$response->header('Content-Type', 'application/json');
$response->end(json_encode([
'event_loop_lag_ms' => $stats['event_loop_lag_ms'],
'event_loop_lag_max_ms' => $stats['event_loop_lag_max_ms'],
'event_loop_lag_avg_ms' => $stats['event_loop_lag_avg_ms'],
]));
return;
}
$response->end("Hello World\n");
});
$server->start();
<?php
use OpenSwoole\Http\Server;
use OpenSwoole\Http\Request;
use OpenSwoole\Http\Response;
use OpenSwoole\Timer;
$server = new Server("0.0.0.0", 9501);
$server->set([
'worker_num' => 4,
]);
$server->on("workerStart", function (Server $server, int $workerId) {
// Check event loop lag every 5 seconds
Timer::tick(5000, function () use ($server) {
$stats = $server->stats();
$lagMs = $stats['event_loop_lag_ms'] ?? 0;
if ($lagMs > 100) {
// Log a warning if event loop lag exceeds 100ms
error_log(sprintf(
"[WARNING] High event loop lag: %.2fms (max: %.2fms, avg: %.2fms) worker_id=%d",
$lagMs,
$stats['event_loop_lag_max_ms'],
$stats['event_loop_lag_avg_ms'],
$server->getWorkerId()
));
}
});
});
$server->on("request", function (Request $request, Response $response) {
$response->end("Hello World\n");
});
$server->start();
<?php
use OpenSwoole\Http\Server;
use OpenSwoole\Http\Request;
use OpenSwoole\Http\Response;
$server = new Server("0.0.0.0", 9501);
$server->on("request", function (Request $request, Response $response) use ($server) {
if ($request->server['request_uri'] === '/metrics') {
$stats = $server->stats(\OpenSwoole\Constant::STATS_OPENMETRICS);
$response->header('Content-Type', 'text/plain; version=0.0.4');
$response->end($stats);
return;
}
$response->end("Hello World\n");
});
$server->start();
The OpenMetrics output includes event loop lag metrics:
# TYPE openswoole_event_loop_lag_ms gauge
openswoole_event_loop_lag_ms 0.052
# TYPE openswoole_event_loop_lag_max_ms gauge
openswoole_event_loop_lag_max_ms 1.203
# TYPE openswoole_event_loop_lag_avg_ms gauge
openswoole_event_loop_lag_avg_ms 0.087
hook_flags to ensure all I/O operations are non-blocking