beyondcode/laravel-query-detector
Detect N+1 database queries in Laravel during development. Monitors queries in real time and alerts you when repeated queries indicate missing eager loading, helping you optimize performance and reduce unnecessary database calls.
Installation:
composer require beyondcode/laravel-query-detector --dev
The package auto-registers in Laravel (Lumen requires manual registration in bootstrap/app.php).
First Use Case:
debug mode (default behavior).User::with('posts')->get()).Where to Look First:
php artisan vendor:publish --provider="BeyondCode\QueryDetector\QueryDetectorServiceProvider").config/querydetector.php for available outputs (Alert, Console, Debugbar, etc.).threshold (default: 1) to control sensitivity (e.g., threshold: 3 ignores queries executed ≤3 times).Local Development:
Use Alert or Console outputs to catch N+1 queries during feature development.
Example: Add User::with('posts')->get() to a controller and see alerts for missing eager loading.
API Development:
Enable Json output to log N+1 warnings in API responses (useful for GraphQL/REST endpoints).
// config/querydetector.php
'output' => [
\BeyondCode\QueryDetector\Outputs\Json::class,
],
Testing:
Disable in production by setting enabled: false in .env or config.
QUERY_DETECTOR_ENABLED=false
morphTo or cached queries).
// config/querydetector.php
'except' => [
User::class => [
Post::class,
'posts',
],
],
\BeyondCode\QueryDetector\Events\QueryDetected for advanced integrations (e.g., Slack alerts, Sentry logging).
// app/Listeners/LogNPlusOneToSentry.php
public function handle(QueryDetected $event) {
Sentry::captureMessage("N+1 Query Detected: {$event->query}");
}
GitHub Actions:
Fail builds if N+1 queries exceed a threshold (requires custom script or Json output parsing).
# .github/workflows/performance.yml
- name: Check N+1 Queries
run: |
php artisan query:detect | grep -q "N+1" && exit 1 || exit 0
Debugbar for QA:
Use Debugbar output in staging to audit query patterns before production.
'output' => [
\BeyondCode\QueryDetector\Outputs\Debugbar::class,
],
Clockwork Integration: Log N+1 queries to Clockwork for detailed request analysis.
'output' => [
\BeyondCode\QueryDetector\Outputs\Clockwork::class,
],
Requires itsgoingd/clockwork.
Dynamic Thresholds: Adjust thresholds per environment (e.g., stricter in CI).
QUERY_DETECTOR_THRESHOLD=0 # Fail on any N+1 in CI
False Positives:
morphTo) may trigger alerts.config/querydetector.php under except.'except' => [
Activity::class => [
Post::class,
'post',
Comment::class,
'comment',
],
],
Debugbar Conflicts:
barryvdh/laravel-debugbar vs. fruitcake/laravel-debugbar) are installed.Lumen Quirks:
bootstrap/app.php:
$app->register(\BeyondCode\QueryDetector\LumenQueryDetectorServiceProvider::class);
JSON Output Edge Cases:
Json output is enabled and responses are parsed correctly.Backtrace Noise:
Isolate Queries:
threshold: 0 to catch all N+1 queries during debugging.QUERY_DETECTOR_THRESHOLD=0
Log-Only Mode:
Log output to persist findings for later review:'output' => [
\BeyondCode\QueryDetector\Outputs\Log::class,
],
Clockwork Deep Dives:
Custom Outputs:
Event Listeners:
QueryDetected events.public function handle(QueryDetected $event) {
if ($event->count > 5) {
Slack::alert("Critical N+1: {$event->query}");
}
}
Dynamic Whitelisting:
public function handle(Request $request, Closure $next) {
config(['querydetector.enabled' => $request->user()->isAdmin()]);
return $next($request);
}
Performance Budgets:
spatie/laravel-performance-monitor to correlate N+1 queries with overall request latency.Testing:
$this->expectsEvents(QueryDetected::class);
How can I help you explore Laravel packages today?