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

Lada Cache Laravel Package

spiritix/lada-cache

Redis-backed, fully automated query cache for Laravel. Transparently caches Eloquent/Query Builder queries with granular invalidation (rows/tables), scales across Redis/cluster setups, supports include/exclude tables, and integrates with Laravel Debugbar.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require spiritix/lada-cache
    php artisan vendor:publish --provider="Spiritix\LadaCache\LadaCacheServiceProvider"
    
  2. Enable in .env:

    LADA_CACHE_ACTIVE=true
    
  3. Add Trait to Models:

    use Spiritix\LadaCache\Database\LadaCacheTrait;
    
    class User extends Model
    {
        use LadaCacheTrait;
    }
    

    (Best practice: Extend a BaseModel with the trait.)

  4. Verify Redis Connection: Ensure your config/database.php has a Redis connection named cache (default) or update lada-cache.php to match your Redis connection name.

First Use Case

Run a query and observe automatic caching:

$user = User::find(1); // Automatically cached

Check Debugbar (if enabled) for cache hits/misses.


Implementation Patterns

Core Workflow

  1. Transparent Caching:

    • All Eloquent/Query Builder queries are cached automatically.
    • No manual Cache::remember() calls needed.
  2. Granular Invalidation:

    • Write operations (insert/update/delete) invalidate only affected rows/tables.
    • Example: Updating users invalidates only the cached users row, not the entire table.
  3. Debugging & Monitoring:

    • Use Debugbar to visualize cache hits/misses/invalidations.
    • Console commands for management:
      php artisan lada-cache:flush       # Clear all cache
      php artisan lada-cache:disable     # Temporarily disable
      php artisan lada-cache:enable      # Re-enable
      

Integration Tips

  • Multi-Database Apps: Configure lada-cache.php to specify which tables/models to cache per connection.

    'exclude_tables' => [
        'connection1' => ['ignored_table'],
        'connection2' => ['another_table'],
    ],
    
  • Bypassing Cache: Use withoutCache() for freshness-critical queries:

    User::where('active', true)->withoutCache()->get();
    
  • Custom Redis Connection: Override the default Redis connection in lada-cache.php:

    'redis_connection' => 'custom_redis',
    
  • Model-Level Control: Exclude specific models from caching via config/lada-cache.php:

    'exclude_models' => [
        'App\Models\UncachedModel',
    ],
    
  • Migrations & Cache: Lada auto-flushes cache after migrations (via MigrationsEnded event).

Advanced Patterns

  • Tag-Based Invalidation: Leverage Redis tags for complex invalidation logic (e.g., invalidate all users with role:admin).

    // In a service or observer
    Cache::tags(['users:admin'])->flush();
    
  • Cache Key Customization: Override cache key generation for specific queries:

    User::query()->withCacheKey('custom_prefix:user:{id}')->find(1);
    
  • Connection-Specific Caching: Use DB::connection('mysql')->table(...) to ensure queries use the correct cached connection.


Gotchas and Tips

Pitfalls

  1. Composite Primary Keys:

    • Row-level invalidation falls back to table-level if the primary key isn’t a single column.
    • Fix: Ensure models use single-column primary keys or configure lada-cache.php to exclude such tables.
  2. Raw SQL Bypasses Cache:

    • Queries via DB::select(), DB::statement(), or raw PDO bypass caching.
    • Fix: Use Query Builder or Eloquent instead.
  3. Third-Party Query Builders:

    • Custom query builders (e.g., from packages) may not integrate with Lada.
    • Fix: Extend Spiritix\LadaCache\Database\Query\Builder or wrap queries in withoutCache().
  4. Debugbar Conflicts:

    • If Debugbar isn’t installed, disable LADA_CACHE_DEBUGBAR in .env to avoid errors.
    • Fix:
      LADA_CACHE_DEBUGBAR=false
      
  5. Cache Key Collisions:

    • Complex queries (e.g., with UNION, EXISTS) may generate ambiguous keys.
    • Fix: Use withoutCache() for problematic queries or report to maintainers.
  6. Redis Connection Issues:

    • If Redis is down, queries fall back to uncached execution (no errors).
    • Fix: Monitor Redis health and set up alerts.
  7. Pessimistic Locks Bypass Cache:

    • lockForUpdate()/sharedLock() queries are never cached.
    • Fix: Use withoutCache() explicitly if needed for locked queries.

Debugging Tips

  1. Check Cache Hits/Misses:

    • Enable Debugbar and inspect the "Lada Cache" panel.
    • Look for CacheMiss or CacheHit entries.
  2. Log Invalidation Events:

    • Enable logging in lada-cache.php:
      'log_invalidations' => true,
      
    • Check storage/logs/laravel.log for invalidation events.
  3. Verify Cache Keys:

    • Use dd() to inspect the cache key for a query:
      $query = User::where('active', true);
      dd($query->getQuery()->toSql(), $query->getCacheKey());
      
  4. Test Invalidation:

    • Manually trigger invalidation and verify:
      User::find(1)->update(['name' => 'New']);
      // Check if the cached row is invalidated
      
  5. Redis CLI Inspection:

    • Use Redis CLI to verify tags/keys:
      redis-cli keys "*"          # List all keys
      redis-cli smembers users:1  # Check row-level tags
      

Performance Quirks

  1. Large Payloads:

    • Caching queries returning >500MB may slow down Redis.
    • Fix: Exclude such queries or use pagination.
  2. Complex Joins:

    • Deeply nested joins may reduce cache effectiveness.
    • Fix: Simplify queries or cache at a higher level (e.g., model collections).
  3. Write-Heavy Workloads:

    • Frequent writes invalidate cache aggressively.
    • Fix: Adjust lada-cache.php to increase TTL or exclude volatile tables.

Extension Points

  1. Custom Cache Key Generation: Override getCacheKey() in your model:

    public function getCacheKey()
    {
        return 'custom:key:' . $this->id;
    }
    
  2. Custom Invalidation Logic: Extend the invalidator:

    use Spiritix\LadaCache\Database\Invalidator;
    
    class CustomInvalidator extends Invalidator
    {
        protected function getTagsForModel($model)
        {
            return ['custom:tag:' . $model->id];
        }
    }
    

    Register in AppServiceProvider:

    LadaCache::setInvalidator(new CustomInvalidator());
    
  3. Redis Connection Hooks: Extend Redis connection logic:

    LadaCache::extendRedisConnection(function ($connection) {
        return Redis::connection($connection)->withTimeout(2.5);
    });
    
  4. Event Listeners: Listen to cache events (e.g., LadaCacheCached, LadaCacheInvalidated):

    use Spiritix\LadaCache\Events\CacheHit;
    
    CacheHit::listen(function ($event) {
        Log::debug('Cache hit for:', [$event->query, $event->key]);
    });
    
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata