hishabee / laravel-query-cache
Smart SQL query caching for Laravel with tag-based invalidation
Requires
- php: ^7.2.5|^7.3|^7.4|^8.0
- greenlion/php-sql-parser: ^4.5
- illuminate/support: ^6.0|^7.0|^8.0|^9.0|^10.0
Requires (Dev)
- orchestra/testbench: ^4.0|^5.0|^6.0|^7.0|^8.0
- phpunit/phpunit: ^8.0|^9.0
This package is auto-updated.
Last update: 2025-05-19 10:44:07 UTC
README
Smart SQL query caching for Laravel with tag-based invalidation and precise cache clearing.
Features
- Automatic query caching with intelligent tag-based invalidation
- Support for explicit query-level cache control
- Smart cache invalidation based on WHERE clauses
- Configurable caching strategy (all queries or manual)
- Works with Laravel 7.0 and above
- Compatible with Redis and Memcached
- Cache stampede prevention
Installation
composer require hishabee/laravel-query-cache
The package will automatically register its service provider.
Configuration
Publish the configuration file:
php artisan vendor:publish --tag=query-cache-config
Add these variables to your .env
file:
QUERY_CACHE_ENABLED=true QUERY_CACHE_STRATEGY=manual QUERY_CACHE_DURATION=3600 QUERY_CACHE_STORE=redis
Basic Usage
// Cache a specific query for 1 hour User::where('active', true) ->cache(3600) ->get(); // Cache with default duration from config Post::latest() ->cache() ->paginate(); // Disable cache for a specific query (when strategy is 'all') Order::where('status', 'pending') ->cache(false) ->get();
How It Works
Tag-Based Caching
The package uses a sophisticated tagging system to enable precise cache invalidation:
- Table-Level Tags
// Query: User::where('active', true)->cache()->get(); // Generated Tags: [ 'table:users', // Base table tag 'where:users:active:1' // Condition tag ]
- Multiple Conditions
// Query: User::where('active', true) ->where('role', 'admin') ->cache() ->get(); // Generated Tags: [ 'table:users', 'where:users:active:1', 'where:users:role:admin' ]
Cache Invalidation
When a table is updated, the package intelligently invalidates only relevant cached queries:
// Original cached query User::where('role', 'admin')->cache()->get(); // When this update happens: User::where('role', 'user')->update(['active' => false]); // Only cache entries with these tags are invalidated: [ 'table:users', 'where:users:role:user' ] // The cached 'admin' query remains valid!
Cache Keys
Cache keys are generated based on the full query including bindings:
$key = 'query_cache:' . md5($fullQuery); // Example: // SELECT * FROM users WHERE active = '1' // Becomes: query_cache:a1b2c3d4e5f6...
Smart Cache Duration
You can set cache duration at multiple levels:
- Global Default (in config)
'duration' => env('QUERY_CACHE_DURATION', 3600),
- Per Query
User::where('active', true) ->cache(7200) // Cache for 2 hours ->get();
Advanced Usage
Working with Complex Queries
// Multiple joins User::join('orders', 'users.id', '=', 'orders.user_id') ->join('products', 'orders.product_id', '=', 'products.id') ->where('orders.status', 'completed') ->cache() ->get(); // Nested conditions User::where(function($query) { $query->where('role', 'admin') ->orWhere('role', 'manager'); }) ->cache() ->get();
Manual Cache Control
// Clear cache for specific table Cache::tags(['table:users'])->flush(); // Clear cache for specific condition Cache::tags(['where:users:role:admin'])->flush();
Debugging Cache Behavior
Enable debug mode in your .env:
QUERY_CACHE_DEBUG=true
This will log:
- Cache hits/misses
- Generated tags
- Cache invalidations
Example log output:
[Query Cache] Hit: SELECT * FROM users WHERE active = '1'
[Query Cache] Tags: table:users, where:users:active:1
[Query Cache] Invalidated tags: table:users, where:users:role:admin
Performance Considerations
-
Cache Store
- Redis (recommended) or Memcached required for tag support
- File cache driver doesn't support tags
-
Cache Duration
- Shorter durations for frequently updated tables
- Longer durations for static/reference data
-
Excluded Tables
- Add frequently updated tables to
excluded_tables
in config - Consider excluding tables with sensitive data
- Add frequently updated tables to
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License. See LICENSE.md for details.