Weave 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

Profiler Laravel Package

link0/profiler

link0/profiler is a Laravel/PHP profiler package for inspecting application performance and debugging during development. It helps surface request timings, database queries, and runtime details so you can identify bottlenecks and optimize your app.

Deep Wiki
Context7

Getting Started

The package is a thin profiling wrapper: it starts/stops an XHProf (or uprofiler) run, collects the raw profile data, and hands it to a persistence layer (file, DB, etc.) so you can inspect it later. Your first step is confirming the runtime dependency exists, because nothing in the package works without it.

  1. Install the PHP extension first, not the package. The package is a client for xhprof/uprofiler, so verify one is available:
    php -m | grep -i xhprof   # or uprofiler
    
    On modern PHP you'll almost certainly need tideways_xhprof (the maintained fork) rather than the abandoned PECL xhprof. Decide that before you composer require link0/profiler.
  2. Require the package and register it. If a Laravel service provider is shipped, publish it; if not, bind the profiler/storage in a service provider manually:
    composer require link0/profiler
    
  3. Where to look first. Open the package source and identify the three moving parts: (a) the profiler driver that talks to the extension, (b) the storage/persistence adapter, and (c) any report/rendering class. Those three are the whole surface area. Also check the README/examples for the exact start()/stop() (or enable()/disable()) method names — the API is small and stable, so a few minutes in the source saves guesswork.
  4. First use case. Don't profile a whole app yet. Profile one known-slow Artisan command or a single controller action, write the result to the file adapter, and confirm a profile artifact is produced. Once you can see raw output, wire in the viewer.

A minimal script to prove the pipeline end-to-end:

$profiler = new \Link0\Profiler\Profiler($config);
$profiler->start('checkout-flow');
// ... work under examination ...
$profiler->stop(); // persists the run via the configured adapter

If that produces a readable profile, you're past the hard part; everything else is selection and workflow.

Implementation Patterns

Sample, don't blanket-profile. Profiling has real overhead and profile artifacts are large. The durable pattern is to profile selectively: a query-string flag, a header, or a profile environment toggle that only activates on staging. Keep the call site identical across environments and let config decide whether data is actually written.

Middleware for web requests. The most common integration is a middleware that starts the profiler on request entry and stops it before the response leaves, tagging the run with route, method, and a correlation ID. This gives you per-request profiles without editing controllers. Guard it so /health, assets, and admin routes are excluded.

Storage as a swappable concern. The package's value is the persistence abstraction — pick a file adapter locally and a DB/Redis adapter for shared or team environments. Treat the storage choice as deployment config, not code. Wrap the adapter in your own factory so you can add retention/cleanup logic without touching vendor code.

Name your runs meaningfully. Use run labels that encode context — route, user tier, feature flag, commit SHA. Profiles are useless in aggregate if every run is named profile. A convention like {route}:{sha}:{flag} makes later comparison possible.

Profile targeted blocks for algorithm work. For a suspected N+1 or hot loop, wrap just that block:

$profiler->start('cart-recalc');
$this->recalculateCart($cart);
$profiler->stop();

This keeps artifacts small and makes the diff between "before" and "after" obvious.

Workflow: capture → compare → verify. Capture a baseline profile, make one change, capture again, and diff. Keep the persistence layer long-lived enough to compare across a release window, then prune aggressively. If the package doesn't ship a diff tool, export the raw profile and use the standard XHProf UI / a flamegraph tool against the same format.

CI gate (optional but powerful). Point the file adapter at a CI artifact directory, run a smoke test that exercises a critical path, and publish the profile alongside test results. It won't gate on wall-clock (too noisy), but it makes regressions visible in review.

Gotchas and Tips

Extension mismatch is the #1 failure. xhprof, uprofiler, and tideways_xhprof produce similar but not identical output and have different function names (xhprof_enable vs tideways_xhprof_enable). The package description mentions XHProf or uprofiler — confirm which driver path it actually selects on your PHP version, and don't mix a tideways_xhprof install with the XHProf driver. A silent no-op (no profile file, no error) is the usual symptom.

"Enabled" is not "profiled." Many libraries silently skip when no extension is present. Add an explicit assertion in your bootstrap that the profiler reports an available driver, so a missing extension fails loudly on staging instead of quietly producing empty reports.

Watch overhead and memory. XHProf holds a call tree in memory; deep recursion or millions of calls can balloon the process. Cap it with the extension's own options (e.g. ignore functions, max depth) and avoid profiling hot loops in production. Treat any always-on production profiling as a deliberate, sampled decision — not a default.

Storage grows fast. File adapters never clean up. Plan a retention policy from day one: a cron/Artisan command that deletes artifacts older than N days, or a TTL on the DB/Redis adapter. Also watch permissions — the web/PHP-FPM user must be able to write the storage directory.

Naming and nesting discipline. If your code starts and stops the profiler recursively, ensure the package's stop() semantics match your expectation (last-stop wins vs. stack). Otherwise nested runs collapse into one confusing artifact. Keep a single owner of start/stop per request where possible.

Laravel config cache. If a config file is published, remember php artisan config:cache freezes profiling settings. Toggling profiling via env vars in a cached-config deploy will appear to do nothing until you clear and rebuild the cache. Prefer a runtime gate (middleware check) over env-only toggles.

Don't ship the viewer to production. The report UI and raw profile endpoints can leak internal paths, SQL, and call graphs. Restrict to local/staging, behind auth, or gate on an environment check.

Extension points are thin — own the glue. This is a small, single-purpose library. Put your own factory/binding around the profiler and storage adapters so upgrades don't ripple through call sites, and so adding a new backend or a sampling policy is a one-file change. Pin the version in composer.json; a package this small with 14 stars won't have a large maintenance buffer, so be prepared to fork or vendor it if a PHP upgrade breaks the driver.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core