laracraft-tech/laravel-xhprof
Integrate XHProf profiling into your Laravel app to measure request performance, capture CPU/memory metrics, and analyze call graphs. Includes middleware/collectors to enable profiling per route or environment and store runs for later review.
composer require laracraft-tech/laravel-xhprof
php artisan vendor:publish --tag=xhprof-config
php artisan vendor:publish --tag=xhprof-migrations
php artisan migrate
php.ini (ensure extension=xhprof.so is uncommented and XHPROF_SAMPLE_RATE is set, e.g., XHPROF_SAMPLE_RATE=100 for full profiling or 10 for sampling).?profile=1 to any Laravel route (e.g., http://your-app.test/api/orders?profile=1)./xhprof (default route) or use the CLI command:
php artisan xhprof:view
Wrap your Artisan command logic with the facade:
use LaracraftTech\Xhprof\Facades\Xhprof;
public function handle()
{
Xhprof::start('cli-job');
// Your logic here...
$profile = Xhprof::stop();
// Optionally save or log the profile
}
/api/orders is slow).?profile=1 to the URL.app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
// ...
\LaracraftTech\Xhprof\Http\Middleware\Profile::class,
],
];
/xhprof for the latest profile.phpunit/phpunit with assertions).use LaracraftTech\Xhprof\Facades\Xhprof;
use Tests\TestCase;
class PerformanceTest extends TestCase
{
public function test_api_response_time()
{
Xhprof::start('api-performance-test');
$response = $this->get('/api/orders');
$profile = Xhprof::stop();
$wallTime = $profile->getWallTime();
$this->assertLessThan(500, $wallTime, "API response time exceeds 500ms");
}
}
php artisan test --filter PerformanceTest
use LaracraftTech\Xhprof\Facades\Xhprof;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
class ProcessOrders implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;
public function handle()
{
Xhprof::start('process-orders-job');
// Job logic here...
$profile = Xhprof::stop();
// Log or save the profile for review
file_put_contents(storage_path('logs/xhprof-job.log'), print_r($profile, true));
}
}
php artisan queue:work
storage/logs/xhprof-job.log or database.\LaracraftTech\Xhprof\Http\Middleware\Profile runs early in the middleware stack to capture full request time.local, staging) in config/xhprof.php:
'enabled' => env('APP_ENV') !== 'production',
skip_urls:
'skip_urls' => [
'health-check',
'ping',
'admin/*',
],
config/xhprof.php:
'storage' => 'file',
Storage interface for S3 or other backends.XHProf Extension Missing:
Call to undefined function xhprof_enable().pecl install xhprof
Add to php.ini:
extension=xhprof.so
XHPROF_SAMPLE_RATE=100
php -m | grep xhprof.Database Storage Bloat:
xhprof_runs table grows large, slowing queries.php artisan xhprof:prune --days=30
Or switch to file storage.Middleware Order Issues:
\LaracraftTech\Xhprof\Http\Middleware\Profile to the top of the middleware stack in app/Http/Kernel.php.Case Sensitivity in Skip Rules:
/Health are not skipped when skip_urls contains 'health'.'skip_urls' => [
'/health',
'/Health',
],
Blob Data Truncation (MySQL):
xhprof_runs table uses LONGTEXT for the data column (handled in v1.0.10+ migrations). If upgrading, run:
php artisan migrate --force
CLI Profiling Overhead:
XHPROF_SAMPLE_RATE=10) or profile selectively:
if (env('PROFILE_CLI')) {
Xhprof::start('cli-job');
// ...
Xhprof::stop();
}
php artisan xhprof:view to inspect the latest profile.$profile = Xhprof::stop();
file_put_contents(storage_path('logs/xhprof-' . now()->timestamp . '.log'), print_r($profile, true));
git bisect with profiling to identify when a regression was introduced:
git bisect start
git bisect bad # Current commit is slow
git bisect good # Previous commit was fast
Profile each bisect step to pinpoint the culprit.Custom Storage Backend:
LaracraftTech\Xhprof\Contracts\Storage interface:
namespace App\Xhprof;
use LaracraftTech\Xhprof\Contracts\Storage;
class S3Storage implements Storage
{
public function save($data, $runId)
{
// Save to S3
}
public function get($runId)
{
// Retrieve from S3
}
}
$this->app->bind(
\LaracraftTech\Xhprof\Contracts\Storage::class,
App\Xhprof\S3Storage::class
);
Custom Middleware:
\LaracraftTech\Xhprof\Http\Middleware\Profile to addHow can I help you explore Laravel packages today?