A Laravel request profiler that captures the complete execution flow of every request — queries, events, views, cache, mail, jobs, HTTP calls, Inertia props, Eloquent models, and full lifecycle timing — all in a Dracula-themed dashboard.
- PHP 8.4+
- Laravel 12 or 13
- Any database Laravel supports (SQLite, MySQL/MariaDB, PostgreSQL). Profiles live in your default connection.
Until the package is on Packagist, add the GitHub repository to your app's composer.json:
{
"repositories": [
{ "type": "vcs", "url": "https://github.com/LaravelPlus/digdeep" }
]
}Then install it as a dev dependency and run the migrations:
composer require laravelplus/digdeep --dev
php artisan migrateTo customise the tables, publish the migrations first (php artisan vendor:publish --tag=digdeep-migrations).
DigDeep auto-registers via its service provider. Open /digdeep in your browser.
Publish the config file:
php artisan vendor:publish --tag=digdeep-config| Option | Default | Description |
|---|---|---|
enabled |
unset | Unset = on only in local/testing. DIGDEEP_ENABLED=true/false forces it. |
show_debugbar |
true |
Inject the floating toolbar into HTML pages (authorized viewers only) |
code_actions |
unset | Artisan command box + AI "apply fix". Unset = local only (DIGDEEP_CODE_ACTIONS) |
sample_rate |
1.0 |
Share of requests to profile (DIGDEEP_SAMPLE_RATE). Streamed and binary responses are never stored. |
auto_profile |
true |
Profile every web request |
max_profiles |
200 |
Stored profiles kept (oldest pruned) |
max_profile_size_kb |
512 |
Per-profile payload cap |
thresholds.* |
see config | Auto-tag slow/heavy requests and fire ThresholdExceeded |
ai_provider / ai_key / ai_model |
unset | Optional AI suggestions (anthropic or openai) |
ignored_paths |
[...] |
URL prefixes to skip |
Once installed, visit:
http://your-app.test/digdeep
DigDeep only activates in local and testing environments by default.
When auto_profile is enabled, every web request is automatically captured. Browse your application normally and profiles will appear in the dashboard.
Use the URL input on the dashboard to profile any route on demand. Enter a URL, select an HTTP method, and click "Profile". The request is executed server-side and the full execution flow is captured.
DigDeep exposes a small API for programmatic use:
POST /digdeep/api/trigger Profile a URL (params: url, method)
DELETE /digdeep/api/profile/{id} Delete a single profile
POST /digdeep/api/clear Delete all profiles
The main view. Shows all captured profiles with stats, a response time chart, manual profiler, and search/filter controls.
- 4 stat cards: total profiles, avg duration, avg queries, avg memory
- Response time distribution chart (last 30 requests)
- Searchable, filterable profile list
- Top routes sidebar with visit counts
Click any profile to see the full execution breakdown:
- Queries — Every SQL query with bindings, execution time, caller location, and N+1 detection
- Route — Matched route name, action, parameters, middleware stack
- Events — All dispatched events with payload summaries
- Views — Rendered Blade templates with data keys passed
- Cache — Cache hits, misses, and writes with keys
- Inertia — Component name, URL, version, and all props sent to the Vue component
- Mail — Sent emails with subject and recipients
- HTTP Client — Outgoing HTTP requests with method, URL, status, and duration
- Jobs — Dispatched queue jobs with class and queue name
- Request — Full request headers (sanitized) and payload
- Response — Status code, headers, and response body
A route-first view of your application. Lists all registered routes, then click any route to see a vertical lifecycle traceback:
- Request Received — Method, URL, headers, payload, body
- Middleware Pipeline — Every middleware layer in execution order
- Route Matched — Route name, action, parameters
- Controller Action — Executing action with all queries, events, cache ops, models, mail, HTTP calls, and jobs
- View Rendering — Rendered views, Inertia component with full prop data
- Response Sent — Status, duration, memory, headers, body, exceptions
Also shows all loaded service providers.
Scans profiled requests for common issues:
- Missing CSRF protection on POST/PUT/PATCH/DELETE routes
- Missing security headers (X-Content-Type-Options)
- Potentially dangerous SQL patterns
Route performance analysis across all profiles:
- Visit count, avg/min/max duration, avg queries
- Error rate per route
- Status code distribution
Query analysis dashboard:
- Read/write breakdown with totals and averages
- Table access patterns (reads and writes per table)
- Top 20 slow queries (>5ms) with caller locations
- Full SQLite schema introspection (tables, columns, types, indexes, foreign keys, row counts)
Exception tracking:
- All captured exceptions with stack traces
- Grouped by exception class with counts
- Error rate across all profiled requests
Top routes by visit count with visual bar chart.
Every profiled request records:
| Category | Data |
|---|---|
| Request | Method, URL, headers (sanitized), payload, raw body (up to 8KB) |
| Response | Status code, headers, body (up to 16KB), size |
| Queries | SQL, bindings, execution time (ms), caller file:line |
| Events | Event class/name, payload summary |
| Views | Template name, file path, data keys, render timestamp |
| Cache | Key, operation type (hit/miss/write) |
| Subject, recipients | |
| HTTP Client | Method, URL, response status, transfer time |
| Jobs | Job class, queue name |
| Inertia | Component, URL, version, prop summaries, full prop data |
| Models | Model class, operation counts (retrieved/created/updated/deleted) |
| Lifecycle | Phase timing (bootstrap, routing, controller, view rendering, response) |
| Performance | Total duration (ms), peak memory (MB), query count, query time (ms) |
| Exceptions | Class, message, file, line, stack trace (30 frames), previous exception |
DigDeep is a development tool. It records SQL, request data and session contents, and in local it can run artisan commands and edit files under app/.
-
Off outside
local/testingunlessDIGDEEP_ENABLED=true. -
Access: in
local/testingeveryone can open/digdeep. Elsewhere access is denied (404) unless you register a gate:// AppServiceProvider::boot() \LaravelPlus\DigDeep\DigDeep::auth(fn ($request) => $request->user()?->isAdmin() ?? false);
The same gate decides who sees the debugbar.
-
Code actions (artisan runner, AI "apply fix") run only in
localunlessDIGDEEP_CODE_ACTIONS=true. Never enable them on a shared or public server. -
CSRF: dashboard routes use the
webmiddleware group, so every POST/DELETE needs the session CSRF token. -
Redaction (
redactin the config): keys containing anyredact.keysentry (password,token,secret,api_key, …) are masked in payloads, JSON/form bodies (request, response, outgoing HTTP client calls), session values and log context.redact.headers(auth, cookie and CSRF headers) are masked too. Text/XML request bodies are not stored. SQL bindings are masked when bound to a sensitive column (password = ?, insert column lists) or when they look like a password hash (redact.binding_patterns); other bindings are stored, so don't profile against production data. SetDIGDEEP_CAPTURE_RESPONSE_BODIES=falseto stop storing response bodies.
Profiles are stored in the digdeep_profiles and digdeep_route_visits tables on your default connection. Only the latest max_profiles are kept. Use php artisan digdeep:prune or digdeep:clear to clean up manually. Pruning to max_profiles runs on 1 in 10 writes (prune_lottery); to prune only from the scheduler, set it to [0, 1] and schedule digdeep:prune. Each collector keeps at most 500 entries (limits.max_entries); totals such as query count still include everything.
composer test # Pest + Testbench
composer lint # Pint
composer analyse # LarastanSee CONTRIBUTING.md and SECURITY.md.
- Backend: Laravel 12, SQLite, PHP 8.4
- Frontend: Vue 3 (CDN), Tailwind CSS v4 with Dracula theme
- Storage: PDO SQLite with JSON data column
- Middleware: Global HTTP middleware with sub-request profiling
MIT