XHProf — Performance Profiling
Your app is slow and you don't know why. Memory grows and you can't find the leak. XHProf profiling with Buggregator lets you see exactly which functions consume CPU, wall time, and memory — without setting up Blackfire or any paid profiling service. Profile data goes to the same Buggregator where you already see your exceptions and logs.
Watch introduction video on YouTube.
Use cases
- Find slow functions — the Call Graph and Top Functions table show exactly where time is spent.
- Detect memory leaks — track memory allocation per function in long-running workers and daemons.
- Measure optimizations — compare two profiler runs side-by-side to verify your changes actually helped.
- Profile any request — works with web requests, CLI commands, queue jobs, and any PHP code.
- All in one place — profiling data next to exceptions, logs, and dumps in the same dashboard.
Analysis modes
Call Graph
Function calls as a tree. Nodes colored from white to dark red — the darker, the more resources consumed.
Flame Graph
Stacked function calls showing where time is spent. Useful for spotting repetitive or time-consuming operations.
Top Functions
Ranked table of the most expensive function calls — CPU time, wall time, memory, and call count.
Profile Comparison
Compare two profiler runs side-by-side. See performance deltas (faster/slower) for CPU time, wall clock time, and memory usage, with per-function percentage changes.
Setup
1. Install the XHProf extension
pear channel-update pear.php.net
pecl install xhprof2. Install the profiler package
Laravel
composer require --dev maantje/xhprof-buggregator-laravelSpiral Framework
composer require --dev spiral/profiler:^3.0Any PHP project
composer require --dev spiral-packages/profileruse SpiralPackages\Profiler\Profiler;
use SpiralPackages\Profiler\DriverFactory;
use SpiralPackages\Profiler\Storage\WebStorage;
use Symfony\Component\HttpClient\NativeHttpClient;
$storage = new WebStorage(
new NativeHttpClient(),
'http://127.0.0.1/api/profiler/store',
);
$profiler = new Profiler(
storage: $storage,
driver: DriverFactory::detect(),
appName: 'My app',
tags: ['env' => 'local'],
);
$profiler->start();
// Your code here
$profiler->end();3. Configure the endpoint
PROFILER_ENDPOINT=http://profiler@127.0.0.1:8000
PROFILER_APP_NAME="My app"In Docker Compose, replace
127.0.0.1with the Buggregator service name.
Custom client integration
If you're building a custom profiler client, there are three ways to send data:
- HTTP auth — add
profilerto the URL:http://profiler@127.0.0.1:8000 - Header — send
X-Buggregator-Event: profilerorX-Profiler-Dump: true - Endpoint — POST to
/api/profiler/store