Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Xhprof Laravel Package

laracraft-tech/laravel-xhprof

Laravel package to integrate XHProf profiling into your app. Capture and store performance profiles for requests and jobs, view results via a simple UI, and analyze bottlenecks to optimize code and database queries.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Profiling Run

  1. Install the Package

    composer require laracraft-tech/laravel-xhprof
    php artisan vendor:publish --provider="LaracraftTech\Xhprof\XhprofServiceProvider" --tag="migrations"
    php artisan migrate
    
  2. Enable XHProf Extension Add to your php.ini (CLI and web):

    extension=xhprof.so
    XHPROF_SAMPLE_RATE=10  # Adjust for balance between overhead and detail
    
  3. Profile a Request Append ?profile=1 to any route (e.g., http://your-app.test/api/orders?profile=1). View results at /xhprof (default route).

  4. Profile a CLI Command

    use LaracraftTech\Xhprof\Facades\Xhprof;
    
    Xhprof::start('cli-job');
    // Your logic here
    $profile = Xhprof::stop();
    $profile->save(); // Stores in DB or file
    

First Use Case: Debugging a Slow API Endpoint

  1. Identify the slow endpoint (e.g., /api/orders takes 800ms).
  2. Append ?profile=1 and navigate to /xhprof.
  3. Analyze the flame graph to spot:
    • Top CPU consumers (e.g., serialize(), Eloquent::hydrate()).
    • Memory spikes (e.g., collect() on large datasets).
  4. Optimize and re-profile to validate fixes.

Implementation Patterns

Workflows

1. Middleware-Based Profiling (Web Requests)

  • Global Profiling: Add to app/Http/Kernel.php:
    protected $middlewareGroups = [
        'web' => [
            // ...
            \LaracraftTech\Xhprof\Http\Middleware\Profile::class,
        ],
    ];
    
  • Selective Profiling: Apply to specific routes:
    Route::middleware(['profile'])->group(function () {
        Route::get('/api/orders', [OrderController::class, 'index']);
    });
    

2. Conditional Profiling (Env/Route-Based)

Configure in .env:

XHPROF_ENABLED=true
XHPROF_SKIP_URLS=*/health,*/admin/*

Or dynamically in code:

if (app()->environment('staging')) {
    Xhprof::start('staging-request');
}

3. CLI Job Profiling

Wrap Artisan commands or queue jobs:

Xhprof::start('process-invoices');
Invoice::processAll();
$profile = Xhprof::stop();
$profile->save(); // Store for later analysis

4. CI/CD Integration (Performance SLAs)

Add to phpunit.xml:

<php>
    <server name="XHPROF_ENABLED" value="true"/>
</php>

Test in FeatureTest:

public function test_api_performance()
{
    $response = $this->get('/api/orders');
    $this->assertLessThan(300, Xhprof::stop()->getWallTime(), "API too slow!");
}

5. Comparative Profiling (Branch Analysis)

  • Run profiling in a feature branch and staging.
  • Compare flame graphs to identify regressions (e.g., "Wall time increased by 20% in feature/subscriptions").

Integration Tips

Database Storage

  • Use xhprof_runs table for structured queries (e.g., filter by URL, user agent).
  • Example query:
    $slowRuns = \LaracraftTech\Xhprof\Models\Run::where('wall_time', '>', 500)->latest()->limit(10)->get();
    

File Storage

  • Store profiles in storage/app/xhprof/ for large volumes.
  • Configure in .env:
    XHPROF_STORAGE=file
    XHPROF_FILE_PATH=storage/app/xhprof
    

Custom Storage (S3, etc.)

Extend the Storage contract:

use LaracraftTech\Xhprof\Contracts\Storage;

class S3Storage implements Storage {
    public function save(Run $run, $data) { /* ... */ }
    public function list() { /* ... */ }
}

Bind in a service provider:

$this->app->bind(Storage::class, function () {
    return new S3Storage();
});

Visualization

  • Use the built-in /xhprof route for flame graphs.
  • Export to Tideways, Blackfire, or custom dashboards by accessing raw data:
    $profile = \LaracraftTech\Xhprof\Models\Run::find(1);
    $data = $profile->data; // Decoded XHProf JSON
    

Sampling Rate

  • Reduce overhead in CI/staging:
    XHPROF_SAMPLE_RATE=5  # 5% sampling
    
  • Disable in production:
    XHPROF_ENABLED=false
    

Gotchas and Tips

Pitfalls

1. Extension Not Loaded

  • Symptom: Profiles return empty or errors like XHProf not enabled.
  • Fix:
    • Verify with php -m | grep xhprof (CLI and web).
    • Restart PHP-FPM/Apache after enabling the extension.
    • For Docker, ensure xhprof is in docker-php-ext-install:
      RUN docker-php-ext-install xhprof
      

2. Database Bloat

  • Symptom: xhprof_runs table grows uncontrollably.
  • Fix:
    • Prune old runs:
      php artisan xhprof:prune --days=7
      
    • Switch to file storage for high-volume profiling.
    • Add a TTL index:
      Schema::table('xhprof_runs', function (Blueprint $table) {
          $table->timestamp('created_at')->useCurrent();
          $table->index(['created_at']);
      });
      

3. Middleware Order Issues

  • Symptom: Wall time excludes middleware execution (e.g., auth, CORS).
  • Fix: Place the Profile middleware first in the stack:
    $middleware = [
        \LaracraftTech\Xhprof\Http\Middleware\Profile::class,
        \App\Http\Middleware\TrustProxies::class,
        // ...
    ];
    

4. Blob Truncation (MySQL)

  • Symptom: Profile data is cut off in the database.
  • Fix: Run the latest migration (v1.0.10+) or manually alter the schema:
    ALTER TABLE xhprof_runs MODIFY data LONGTEXT;
    

5. CLI Overhead

  • Symptom: Profiling slows down Artisan commands or queues.
  • Fix:
    • Increase XHPROF_SAMPLE_RATE (e.g., 20 for 20% sampling).
    • Disable in production CI:
      XHPROF_ENABLED=false
      

6. Route Skipping Not Working

  • Symptom: XHPROF_SKIP_URLS is ignored.
  • Fix: Ensure the config is published and the pattern matches exactly:
    XHPROF_SKIP_URLS=*/health,*/admin/*
    
  • Test with php artisan config:get xhprof.skip_urls.

Debugging Tips

Verify Profiling is Active

if (!Xhprof::isEnabled()) {
    throw new \RuntimeException("XHProf is not enabled. Check extension and config.");
}

Check Raw Data

Inspect the stored profile data:

$run = \LaracraftTech\Xhprof\Models\Run::latest()->first();
$data = json_decode($run->data, true);
print_r($data['main()']['wt']); // Wall time

Profile a Specific Function

Use XHProf’s built-in markers:

Xhprof::start('custom-marker');
// Code to profile
Xhprof::stop('custom-marker');

Compare Profiles

Use the xhprof_diff tool (included with XHProf) to compare runs:

xhprof_diff run1.xhprof run2.xhprof
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata