Download the PHP package mateffy/laraperf without Composer
On this page you can find all versions of the php package mateffy/laraperf. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download mateffy/laraperf
More information about mateffy/laraperf
Files in mateffy/laraperf
Package laraperf
Short Description Performance analysis toolkit for AI coding agents — SQL query profiling, N+1 detection, EXPLAIN ANALYZE, via Artisan commands outputting structured JSON.
License MIT
Homepage https://github.com/mateffy/laraperf
Informations about the package laraperf
laraperf
Laravel performance analysis CLI tool for AI coding agents. Captures SQL queries, detects N+1 patterns, and runs EXPLAIN ANALYZE — all through short-lived Artisan commands that output structured JSON to stdout. No browser or GUI required.
Why this exists
Standard profiling tools (Debugbar, Clockwork, Telescope) are browser-first. LLM agents work via commands and stdout, not GUIs. Eloquent and Filament generate queries that are invisible at the source level — the agent never sees the PHP that triggers them.
laraperf bridges this gap:
- Capture —
DB::listenattaches to every PHP-FPM request while a session is active. Each request appends its queries to a shared JSON file. The agent reads the file after the fact. - Analyse —
perf:queryoutputs structured JSON: summaries, slow queries, N+1 candidates with source file/line pointing intoapp/code (vendor frames stripped). - Plan —
perf:explainrunsEXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)against any SQL string, with a runtime database-name override for multi-tenant setups.
Installation
Requires PHP 8.3+ and Laravel 11+ (supports 11, 12, 13).
No publish step needed — config is auto-merged. Environment variables:
Commands
perf:watch — Start a capture session
Returns immediately by default (detached mode). The session stays active for 5 minutes, or until perf:stop.
Detached mode (default): Spawns perf:_worker as a background process. The parent exits immediately and prints the session ID.
Sync mode: Blocks the terminal. Handles Ctrl+C via SIGINT/SIGTERM.
perf:stop — Stop detached watchers
Sends SIGTERM, waits up to 2 seconds, then SIGKILL if unresponsive. Finalizes sessions and removes PID sentinels.
perf:query — Analyse captured queries
Reads a completed session and outputs analysis as JSON (status lines go to stderr). When no output flags are given, all three reports are included (summary, slow≥100ms, n1≥3). Flags can be combined freely.
Default (summary + slow + n1):
Each N+1 candidate includes: count, total_time_ms, avg_time_ms, normalized_sql, table, batch_id, example_raw_sql, example_source (app-frame stack trace), and up to 5 example_instances.
Specific reports:
perf:explain — Run EXPLAIN ANALYZE
Runs EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) for PostgreSQL, falls back to plain EXPLAIN for other drivers. For non-SELECT statements, wraps in BEGIN/ROLLBACK to avoid data mutation.
The --db flag patches database.connections.{name}.database at runtime and calls DB::purge() to force a fresh connection. No changes to config/database.php and no tenancy package dependency.
Output:
perf:clear — Delete session files
Removes all session files from storage/perf/. Refuses to run if active watchers are detected.
How it works
PHP-FPM interception
Under PHP-FPM, each web request is a separate process. The background worker can't intercept those requests' queries directly. Instead, LaraperfServiceProvider::packageBooted() checks on every boot whether an active session exists on disk. When found, DB::listen is attached to that request's process. Every request made while the watcher is alive automatically appends its queries to the session JSON. When no session is active, overhead is ~1 glob call.
Session storage
Sessions live in storage/perf/<session_id>.json. Each session is a JSON object with a queries array. Writes are atomic (write to .tmp.{pid}, then rename). Up to 10 completed sessions are retained; older ones are pruned automatically.
PID sentinels are written to storage/perf/.watcher-{pid} by background workers. perf:stop reads these to send SIGTERM.
Add to .gitignore:
Stack trace filtering
QueryLogger captures up to 5 frames from each query's call stack, filtered to app/ and packages/ frames (excluding vendor and framework). Filament/Eloquent queries report the specific Resource, Page, Action, or RelationManager that triggered them — not an anonymous closure inside the framework.
N+1 detection
N1Detector groups queries by (batch_id, normalized_sql_hash). Two queries match when their SQL is structurally identical after stripping all literal values. Groups with count >= 3 (default threshold) are reported as N+1 candidates. Each PHP-FPM request gets a unique batch_id, so N+1s are detected per-request, not across requests.
Typical workflow
Programmatic testing API
laraperf provides a testing API for use in PHPUnit/Pest tests, tinker, or any PHP context. It captures queries, detects N+1 patterns, and measures timing and memory — all in-process, no CLI required.
Global functions
PerformanceResult
measure() and stop() return a PerformanceResult with:
| Method | Returns |
|---|---|
durationMs() |
Total execution time in ms |
peakMemoryBytes() |
Peak memory usage |
netMemoryBytes() |
Memory increase during capture |
peakMemoryHuman() |
Human-readable peak memory (e.g. "2.4 MB") |
queryCount() |
Number of queries executed |
totalQueryTimeMs() |
Total time spent in queries |
slowQueries($thresholdMs) |
Queries slower than threshold |
n1Candidates($threshold) |
N+1 pattern candidates |
hasN1Patterns($threshold) |
Whether any N+1 patterns were found |
tablesAccessed() |
Array of unique table names |
queriesByTable($table) |
Queries for a specific table |
summary() |
Quick overview array |
toArray() / toJson() |
Full serialization |
Pest integration
laraperf auto-registers with Pest. Every test gets automatic performance capture, and you can set declarative constraints.
Constraint methods available on test():
| Method | Description |
|---|---|
->maxQueryCount(int) |
Max allowed queries |
->maxQueryDuration(float) |
Max single query duration in ms |
->maxDuration(float) |
Max total test duration in ms |
->maxDuration(float) |
Alias: maxTotalDuration() |
->maxMemory(string\|int) |
Max memory usage ("10M", "512KB", or bytes) |
->maxN1Candidates(int, int) |
Max N+1 candidate count (with optional threshold) |
->noN1Patterns(int) |
Require zero N+1 patterns |
License
MIT
All versions of laraperf with dependencies
spatie/laravel-package-tools Version ^1.16
illuminate/contracts Version ^11.0||^12.0||^13.0
illuminate/database Version ^11.0||^12.0||^13.0
illuminate/console Version ^11.0||^12.0||^13.0
illuminate/support Version ^11.0||^12.0||^13.0