All posts

PHP Performance Monitoring Best Practices

Optimize PHP application performance with OPcache tuning, query monitoring, profiling tools, and real-time performance alerting strategies.

PHP Performance Monitoring Best Practices

PHP applications can be fast when properly monitored and optimized. Here's how to track and improve performance.

OPcache Configuration

; php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0  ; Disable in production
opcache.revalidate_freq=0

Monitor OPcache hit rates:

$status = opcache_get_status();
$hitRate = $status['opcache_statistics']['hits'] /
    ($status['opcache_statistics']['hits'] + $status['opcache_statistics']['misses']) * 100;
echo "OPcache hit rate: {$hitRate}%";

Database Query Monitoring

class QueryLogger
{
    private array $queries = [];

    public function log(string $sql, float $duration): void
    {
        $this->queries[] = [
            'sql' => $sql,
            'duration_ms' => round($duration * 1000, 2),
            'timestamp' => microtime(true),
        ];

        if ($duration > 1.0) {
            error_log("Slow query ({$duration}s): {$sql}");
        }
    }

    public function getSummary(): array
    {
        return [
            'total_queries' => count($this->queries),
            'total_time_ms' => array_sum(array_column($this->queries, 'duration_ms')),
            'slowest' => max(array_column($this->queries, 'duration_ms')),
        ];
    }
}

Request Timing

// Middleware or bootstrap
$startTime = microtime(true);
register_shutdown_function(function () use ($startTime) {
    $duration = microtime(true) - $startTime;
    $memory = memory_get_peak_usage(true) / 1024 / 1024;

    error_log(json_encode([
        'type' => 'request_metrics',
        'duration_ms' => round($duration * 1000),
        'memory_mb' => round($memory, 2),
        'uri' => $_SERVER['REQUEST_URI'] ?? 'cli',
    ]));
});

Key Metrics

  • Response time (p95) — track per endpoint
  • Query count per request — watch for N+1 patterns
  • OPcache hit rate — should be above 99%
  • Peak memory per request — identify memory-hungry endpoints
  • PHP-FPM pool usage — active vs idle workers

Profiling with Xdebug

Enable profiling selectively:

xdebug.mode=profile
xdebug.start_with_request=trigger
xdebug.output_dir=/tmp/xdebug

Use Bugsly alongside your metrics to correlate performance degradation with specific errors. A sudden increase in 500 errors alongside rising response times often points to a database or external service issue.

Try Bugsly Free

AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.

Get Started Free