daraniya / cache-graph
Laravel cache dependency graph and intelligent cache invalidation package
Requires
- php: ^8.1
- illuminate/support: ^10.0 || ^11.0 || ^12.0 || ^13.0
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0 || ^11.0
- pestphp/pest: ^2.0 || ^3.0 || ^4.0
- pestphp/pest-plugin-laravel: ^2.0 || ^3.0 || ^4.0
Suggests
- ext-redis: Recommended when using the redis graph driver.
- illuminate/database: Required when using the database graph driver.
- illuminate/redis: Required when using the redis graph driver.
This package is not auto-updated.
Last update: 2026-06-02 17:06:30 UTC
README
A small, high-performance Laravel cache dependency graph and intelligent tagless cache invalidation package.
Why Cache Graph?
Laravel cache tags are incredibly useful, but they are not supported by the file, database, dynamodb, or apc cache drivers.
daraniya/cache-graph solves this by introducing a tagless cache dependency graph. It tracks which cache keys depend on which underlying data sources (e.g., specific models, DB tables, API queries). When a source changes, it invalidates all direct and transitive dependent cache keys recursively without needing native cache tag support.
Key Features in v0.1.0
- Tagless Cache Invalidation: Works out of the box on any Laravel cache driver.
- Deep Dependency Chains: Supports recursive invalidations (e.g.,
keyCdepends onkeyBwhich depends onkeyAwhich depends onsourceX). - Multiple Storage Engines:
- JSON/NDJSON (Default): Optimized append-only JSON event log with a small, compiled manifest and exclusive file locking (
flock). - Redis: Ultra-fast in-memory set and hash storage for high-concurrency production environments.
- Database: Standard query builder-driven storage, perfect for unified SQL architectures.
- JSON/NDJSON (Default): Optimized append-only JSON event log with a small, compiled manifest and exclusive file locking (
- Detailed Overhead Metrics:
- Storage Estimation: Estimates memory/storage footprint using precise serialization checks.
- Timings: Tracks
average,max,p95, and total count for operations (get,put,remember,invalidate,flush).
- Aesthetic CLI Reporter: Inspect your cache graph metrics instantly with a single artisan command.
Installation
Requirements
- PHP 8.1+
- Laravel 10, 11, 12, or 13
Install the package via Composer:
composer require daraniya/cache-graph
If you plan to use the Database driver, publish and run the migrations:
php artisan vendor:publish --tag="cache-graph-migrations"
php artisan migrate
Publish the config file:
php artisan vendor:publish --tag="cache-graph-config"
Configuration
The config file is published at config/cache-graph.php:
return [ // Enable/disable graph tracking while keeping cache operations working 'enabled' => env('CACHE_GRAPH_ENABLED', true), // Auto-load package migrations only when explicitly enabled 'auto_load_migrations' => env('CACHE_GRAPH_AUTO_LOAD_MIGRATIONS', false), // Storage driver: "json", "redis", "database" 'driver' => env('CACHE_GRAPH_DRIVER', 'json'), // Path for the JSON/NDJSON storage 'path' => storage_path('app/cache-graph'), // Redis connection to use for the redis driver 'redis_connection' => env('CACHE_GRAPH_REDIS_CONNECTION', 'default'), // Database connection to use for the database driver 'database_connection' => env('CACHE_GRAPH_DATABASE_CONNECTION'), // Default Cache TTL 'ttl' => env('CACHE_GRAPH_TTL', 3600), // Enable/disable storage overhead monitoring 'store_stats' => env('CACHE_GRAPH_STORE_STATS', true), ];
Disable graph tracking in production without changing application code:
CACHE_GRAPH_ENABLED=false
When disabled, get, put, remember, and forget pass through to Laravel's cache. Dependency tracking, invalidation, metrics, and graph storage writes are skipped.
Usage
1. Retrieve & Cache with Dependencies (remember)
use Daraniya\CacheGraph\Facades\CacheGraph; $userProfile = CacheGraph::remember('user_profile_1', 3600, function () { return User::find(1)->toProfileArray(); }, ['users_table', 'user:1']);
2. Standard Cache Operations (get & put)
// Retrieve a value and automatically increment hit/miss counters $profile = CacheGraph::get('user_profile_1'); // Cache a value and link it to dependencies CacheGraph::put('user_profile_1', $profileData, 3600, ['users_table', 'user:1']);
3. Register Edges Manually (dependsOn)
CacheGraph::dependsOn('dashboard_stats', ['users_table', 'transactions_table']);
4. Smart Recursive Invalidation (invalidateSource)
Invalidating a dependency source will automatically forget all associated cache keys and trace downstream dependencies.
// When User 1 is updated: CacheGraph::invalidateSource('user:1');
Metric & Storage Formulas
Storage Overhead Estimation
The total storage overhead of a cache key in the graph is estimated as:
$$\text{Estimated Storage} = \text{Payload Bytes} + \text{Metadata Bytes} + \text{Dependency Edges Bytes} + \text{Reverse Index Bytes}$$
- Payload Bytes: The length of the serialized cache value (
strlen(serialize($value))). - Metadata Bytes: Overhead of storing key metadata (TTL, creation time, size counters).
- Dependency Edges Bytes: Bytes consumed by tracking links from key to dependency list.
- Reverse Index Bytes: Bytes consumed by tracking links in reverse lookup index (source to key list).
Operation Timings
The package tracks time elapsed in milliseconds for the following operations:
getputrememberinvalidateflush
Stats computed include average, max, 95th percentile (p95), and total operation count.
CLI Report Command
Run the report command to print a beautiful, structured overview of your cache graph:
php artisan cache-graph:report
If CACHE_GRAPH_ENABLED=false, the command exits successfully and reports that tracking is disabled.
Example CLI Output:
Generating Cache Graph Report...
Active Storage Driver: json
Global Counters:
+---------------+-------+
| Counter | Value |
+---------------+-------+
| Hits | 1205 |
| Misses | 45 |
| Writes | 40 |
| Forgets | 2 |
| Invalidations | 4 |
+---------------+-------+
Operation Timings (ms):
+------------+-----------+----------+-----------------------+------------------+
| Operation | Average | Max | 95th Percentile (p95) | Total Operations |
+------------+-----------+----------+-----------------------+------------------+
| Get | 0.0821 ms | 2.512 ms | 0.1205 ms | 1250 |
| Put | 0.4512 ms | 5.820 ms | 0.9841 ms | 40 |
| Remember | 0.3205 ms | 8.125 ms | 0.8124 ms | 1250 |
| Invalidate | 1.2501 ms | 4.120 ms | 2.8451 ms | 4 |
| Flush | 0.0500 ms | 0.050 ms | 0.0500 ms | 1 |
+------------+-----------+----------+-----------------------+------------------+
Storage Estimates:
Total Tracked Keys: 38
Total Estimated Overhead: 124.52 KB
Average Storage per Key: 3.28 KB
Top Keys by Storage Overhead (max 10):
+-------------+--------------+-------------------+--------------------+-------------------+
| Cache Key | Payload Size | Metadata Overhead | Dependencies Count | Total Est. Storage|
+-------------+--------------+-------------------+--------------------+-------------------+
| home_feed | 45.21 KB | 250 B | 4 | 46.12 KB |
| user_1_prof | 8.12 KB | 240 B | 2 | 8.84 KB |
| user_2_prof | 7.95 KB | 240 B | 2 | 8.65 KB |
+-------------+--------------+-------------------+--------------------+-------------------+
License
This package is open-sourced software licensed under the MIT license.