Weave Code
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

Laravel Slower Laravel Package

halilcosdu/laravel-slower

Detect and log slow Laravel database queries, then get AI-powered suggestions for indexes and query improvements. Configurable thresholds, can run with or without AI, and supports Laravel 10–13 on PHP 8.2+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation (unchanged):

    composer require halilcosdu/laravel-slower
    php artisan vendor:publish --tag="slower-config"
    php artisan vendor:publish --tag="slower-migrations"
    php artisan migrate
    
  2. Configure .env (additions highlighted):

    SLOWER_ENABLED=true
    SLOWER_THRESHOLD=10000  # Log queries slower than 10ms
    OPENAI_API_KEY=your_openai_key
    OPENAI_ORGANIZATION=your_org_id
    
    # New v3.2.0 controls
    SLOWER_CAPTURE_SAMPLE_RATE=1.0  # 0.0–1.0 (1.0 = always capture)
    SLOWER_CAPTURE_MAX_PER_EXECUTION=100
    SLOWER_ANALYZE_QUEUE=slow_analysis  # Leave unset for sync
    
  3. Enable Query Logging (updated for origin tracking):

    public function boot()
    {
        if (config('slower.enabled')) {
            \DB::enableQueryLog();
            \DB::listen(function ($query) {
                if (\DB::getQueryLog() && \DB::getQueryLog()[0]['time'] > config('slower.threshold')) {
                    \HalilCosdu\Slower\Facades\Slower::capture($query);
                }
            });
        }
    }
    

First Use Case: Debugging a Slow Endpoint

  1. Trigger a slow query (e.g., via API).
  2. New: Check the Grouped view for query fingerprints:
    php artisan slower:events --grouped
    
  3. Drill into a fingerprint to see:
    • Occurrence count
    • Avg/max duration
    • Origin (route/job/command)
    • Code location (if available)

Implementation Patterns

Core Workflow: Query Optimization Loop (Updated)

  1. Capture with Context: Use capture() instead of log() to include origin metadata:

    \HalilCosdu\Slower\Facades\Slower::capture($query);
    
  2. Analyze Asynchronously (new):

    // Dispatch analysis as a background job
    \HalilCosdu\Slower\Facades\Slower::analyze($log)->onQueue('slow_analysis');
    
  3. Review Grouped Events:

    # CLI grouped view (new)
    php artisan slower:events --grouped
    
    # Programmatic access
    $grouped = \HalilCosdu\Slower\Facades\Slower::groupedEvents();
    
  4. Leverage Events (new):

    // Listen for new slow queries
    event(new \HalilCosdu\Slower\Events\SlowQueryCaptured($log));
    
    // Listen for first occurrence of a fingerprint
    event(new \HalilCosdu\Slower\Events\SlowQueryFirstSeen($fingerprint));
    

Integration Tips

  • Sampled Capture (new): Reduce overhead in high-traffic apps:

    SLOWER_CAPTURE_SAMPLE_RATE=0.1  # Capture 10% of slow queries
    
  • Queue Analysis (new): Configure a dedicated queue for analysis:

    SLOWER_ANALYZE_QUEUE=slow_analysis
    

    Then run workers:

    php artisan queue:work --queue=slow_analysis
    
  • Origin Filtering: Filter events by origin (e.g., API routes):

    $apiEvents = \HalilCosdu\Slower\Models\SlowLog::where('origin_route', 'like', '/api%')->get();
    
  • Backfill Fingerprints (one-time):

    php artisan slower:fingerprint  # Chunked, idempotent
    

Gotchas and Tips

Pitfalls

  1. Fingerprint Normalization:

    • False splits: Escaping IN (...) or literals may create duplicate fingerprints. Use:
      SLOWER_FINGERPRINT_ESCAPE_IN_LIST=true  # Default: false
      
    • False merges: Complex queries with dynamic literals may merge incorrectly. Review the Grouped view for anomalies.
  2. Origin Overhead:

    • Backtrace collection adds ~1–2ms per slow query. Disable for non-critical paths:
      \HalilCosdu\Slower\Facades\Slower::capture($query, origin: false);
      
  3. AI Payload Privacy:

    • Default: Only parameterized SQL + schema leaves the app. Enable raw SQL/bindings explicitly:
      SLOWER_AI_PAYLOAD_INCLUDE_RAW_SQL=true
      SLOWER_AI_PAYLOAD_INCLUDE_BINDINGS=true
      
    • Redactor: Misconfiguration throws. Test with:
      php artisan slower:test-redactor
      
  4. Queued Analysis:

    • Jobs fail silently if the record is pruned. Use shouldQueue() to guard:
      $job = \HalilCosdu\Slower\Facades\Slower::analyze($log);
      if ($job && $job->shouldQueue()) {
          $job->onQueue('slow_analysis')->dispatch();
      }
      

Debugging Tips

  • Verify Fingerprints: Check normalization with:

    php artisan slower:fingerprint --dry-run
    
  • Inspect Events: Dump raw event data:

    $event = \HalilCosdu\Slower\Models\SlowLog::find(1);
    dd($event->toArray());
    
  • Queue Issues: Monitor stuck jobs:

    php artisan queue:failed-table
    
  • Circuit Breaker: Storage failures trigger a 60s break. Check logs for:

    [Slower] Circuit breaker armed: storage failure
    

Extension Points

  1. Custom Fingerprint Normalizer: Extend \HalilCosdu\Slower\Services\FingerprintNormalizer to handle edge cases.

  2. Origin Resolvers: Add custom origin resolvers (e.g., for CLI commands):

    \HalilCosdu\Slower\Services\OriginResolver::extend('cli', function () {
        return 'cli:' . $_SERVER['argv'][0];
    });
    
  3. Payload Redactors: Implement \HalilCosdu\Slower\Contracts\PayloadRedactor to sanitize sensitive data:

    class MyRedactor implements PayloadRedactor {
        public function redact(array $payload): array {
            $payload['sql'] = str_replace('password', '[REDACTED]', $payload['sql']);
            return $payload;
        }
    }
    

    Register in config/slower.php:

    'ai_payload' => [
        'redactor' => \App\Services\MyRedactor::class,
    ],
    
  4. Event Listeners: React to slow queries in real-time:

    \Event::listen(\HalilCosdu\Slower\Events\SlowQueryCaptured::class, function ($event) {
        if ($event->log->time > 5000) {
            \Log::alert("Critical slow query: {$event->log->fingerprint}");
        }
    });
    
  5. Grouped View Customization: Override the grouped query builder:

    \HalilCosdu\Slower\Services\GroupedView::macro('customFilter', function () {
        return $this->where('time', '>', 20000);
    });
    

    Usage:

    $grouped = \HalilCosdu\Slower\Facades\Slower::groupedEvents()->customFilter();
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor