Milind Daraniya

Back to Portfolio

Laravel Cache Graph – Tagless Cache Dependency & Invalidation Package

Laravel Package

Role: Creator & Developer

A high-performance Laravel package that introduces a tagless cache dependency graph for intelligent cache invalidation on any cache driver.

Laravel Cache Graph – Tagless Cache Dependency & Invalidation Package

About This Project

Laravel Cache Graph is an open-source PHP package that solves a well-known Laravel limitation — native cache tags are unsupported by the file, database, dynamodb, and apc cache drivers. This package wraps Laravel's Cache facade and adds a dependency graph layer on top. When you cache a value, you specify dependency sources (model IDs, table names, any string). The package records edges between cache keys and their sources. When a source changes, it performs a BFS traversal to recursively find and evict all transitively dependent cache keys. Ships with three storage backends (JSON/NDJSON with file locking, Redis with sets/hashes, and database via SQL migrations), operation timing with p95 metrics, storage overhead estimation, and a beautiful Artisan CLI report command.

Impact

Solves a real Laravel limitation by bringing cache dependency tracking and intelligent invalidation to all cache drivers — including those where native tags are unsupported — with production-ready metrics, multiple storage backends, and clean architecture.

Key Features

  • Tagless cache invalidation that works on any Laravel cache driver (file, database, dynamodb, apc, redis, memcached, array)
  • Deep dependency chain invalidation via BFS traversal for transitive cache clearing
  • Three storage backends: JSON/NDJSON with flock, Redis with sets/hashes, and MySQL/SQLite via migrations
  • Operation timing metrics tracking average, max, p95 latency, and total count per operation
  • Storage overhead estimation with bytes-per-key breakdown and top-key reports
  • Global counters for hits, misses, writes, forgets, and invalidations
  • CLI report command (php artisan cache-graph:report) with formatted tables and metrics
  • Runtime enable/disable toggle via .env or facade methods with zero overhead when disabled
  • Pluggable driver architecture via DriverInterface contract for custom backends
  • Full Pest test suite with unit and feature tests
  • Laravel auto-discovery with service provider and facade
  • Supports Laravel 10, 11, 12, and 13

Complex Features

  • BFS-based recursive invalidation: When invalidateSource() is called, the graph performs a breadth-first traversal to find all transitively dependent cache keys — if keyC depends on keyB which depends on keyA which depends on sourceX, all three keys are evicted in the correct order.
  • Three-storage architecture: JSON/NDJSON driver uses an append-only event log with atomic manifest rebuilds and exclusive file locking (flock) for concurrent safety. Redis driver uses sets for dependency tracking, hashes for metrics, and capped lists for timing samples. Database driver uses three MySQL/SQLite tables with transactional writes.
  • Storage capping strategy: All drivers cap timing samples at 1000 entries using different strategies — Redis uses ltrim, NDJSON compacts the log, database uses counting. This prevents unbounded storage growth in production.
  • Operation timing with p95: Tracks average, max, and p95 latency for get, put, remember, invalidate, and flush operations across all drivers. The p95 calculation sorts timing samples and picks the 95th percentile for realistic performance monitoring.
  • Aesthetic CLI reporter: The cache-graph:report command outputs beautifully formatted tables showing driver info, global counters, per-operation timings, storage estimates, and top cache keys by overhead — making it easy to monitor cache graph performance in production.
  • Pluggable driver system: All drivers implement Daraniya\CacheGraph\Contracts\DriverInterface with get/put/forget/dependsOn/invalidateSource/flush/stats methods. New backends can be added by implementing the interface and registering in config.
  • Zero-overhead bypass mode: When disabled via CACHE_GRAPH_ENABLED=false or CacheGraph::disable(), all calls pass through directly to Laravel's native Cache facade with no graph tracking, no overhead, and no performance impact.

Tech Stack

PHP 8.1 Laravel 10-13 Redis MySQL/SQLite PestPHP Composer