halilcosdu/laravel-slower
Detects slow Laravel database queries, logs them, and uses optional AI recommendations to suggest indexes and other optimizations. Configure thresholds, enable/disable monitoring, and run with Laravel 10–13 on PHP 8.2+ for actionable performance insights.
Installation:
composer require halilcosdu/laravel-slower
php artisan vendor:publish --tag="slower-config"
php artisan vendor:publish --tag="slower-migrations"
php artisan migrate
Enable in AppServiceProvider:
use HalilCosdu\Slower\Slower;
public function boot()
{
Slower::enable();
}
Configure .env:
SLOWER_ENABLED=true
SLOWER_THRESHOLD=10000 # Milliseconds
OPENAI_API_KEY=your_api_key
First Use Case:
Trigger a slow query (e.g., unindexed WHERE on large tables) and check the slow_logs table for captured queries.
Query Capture:
SLOWER_THRESHOLD (default: 10ms).Analysis Pipeline:
$slowLog = \HalilCosdu\Slower\Models\SlowLog::first();
\HalilCosdu\Slower\Facades\Slower::analyze($slowLog);
app/Console/Kernel.php):
$schedule->command(\HalilCosdu\Slower\Commands\AnalyzeQuery::class)
->daily()
->runInBackground();
AI Recommendations (if enabled):
EXPLAIN ANALYZE insights).SLOWER_AI_RECOMMENDATION_MODEL (e.g., gpt-4).Cleanup:
$schedule->command(\HalilCosdu\Slower\Commands\SlowLogCleaner::class)
->daily()
->runInBackground();
Debugging Slow Endpoints: Add middleware to log slow requests:
use HalilCosdu\Slower\Facades\Slower;
public function handle($request, Closure $next)
{
$start = microtime(true);
$response = $next($request);
$duration = (microtime(true) - $start) * 1000;
if ($duration > config('slower.threshold')) {
Slower::logQuery('Request took ' . $duration . 'ms', ['duration' => $duration]);
}
return $response;
}
Custom Query Logging:
Extend the Slower facade to log custom queries:
Slower::logQuery('SELECT * FROM users WHERE email = ?', ['john@example.com'], 'pgsql');
Batch Analysis: Process multiple slow logs in bulk:
$slowLogs = \HalilCosdu\Slower\Models\SlowLog::where('is_analyzed', false)->limit(10)->get();
foreach ($slowLogs as $log) {
Slower::analyze($log);
}
AI Dependency:
SLOWER_AI_RECOMMENDATION=false) removes optimization suggestions but retains query logging.openai-php/laravel logs.Performance Overhead:
SLOWER_IGNORE_INSERT_QUERIES=true to skip INSERT/UPDATE logs.Database-Specific Quirks:
EXPLAIN ANALYZE is supported (enabled by default in config)./*! EXPLAIN */ hints if EXPLAIN ANALYZE fails.Schema Mismatches:
slow_logs table schema changes, reset migrations or manually adjust the resources.table_name config.Verify Logs:
Check slow_logs table for captured queries:
SELECT * FROM slow_logs ORDER BY time DESC LIMIT 10;
AI Debugging:
.env:
OPENAI_API_KEY=sk-xxx
OPENAI_ORGANIZATION=org-xxx
use OpenAI\Laravel\Facades\OpenAI;
OpenAI::completion()->create(['model' => 'gpt-4', 'prompt' => 'Test']);
Query Analysis:
Manually run EXPLAIN ANALYZE in your DB client to cross-validate AI suggestions:
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'john@example.com';
Custom Prompts:
Override the default prompt in config/slower.php:
'prompt' => 'Focus on adding indexes for large tables only. Ignore small tables (<1000 rows).',
Post-Analysis Hooks:
Extend the SlowLog model to trigger actions after analysis:
protected static function booted()
{
static::saved(function ($model) {
if ($model->wasChanged('recommendation')) {
// Send Slack notification, etc.
}
});
}
Filtering Queries: Use Eloquent scopes to filter slow logs:
$slowLogs = \HalilCosdu\Slower\Models\SlowLog::where('time', '>', 5000)
->where('connection', 'pgsql')
->get();
Testing: Mock AI responses in tests:
$this->mock(OpenAI::class)->shouldReceive('completion')
->andReturn(['choices' => [['text' => 'Add index on column `email`']]]);
How can I help you explore Laravel packages today?