PHPackages                             lunzai/laravel-cache-dependency - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. lunzai/laravel-cache-dependency

ActiveLibrary[Caching](/categories/caching)

lunzai/laravel-cache-dependency
===============================

Dependency-based caching for Laravel with tag and database dependencies inspired by Yii2

0.9.0(5mo ago)02MITPHPPHP ^8.2CI passing

Since Nov 26Pushed 5mo agoCompare

[ Source](https://github.com/lunzai/laravel-cache-dependency)[ Packagist](https://packagist.org/packages/lunzai/laravel-cache-dependency)[ Docs](https://github.com/lunzai/laravel-cache-dependency)[ RSS](/packages/lunzai-laravel-cache-dependency/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (2)Used By (0)

Laravel Cache Dependency
========================

[](#laravel-cache-dependency)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d4a6e04598b91fd7e5b7f8c4a30152a08245cce1dc1ecfd69617e3ffb59d27eb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c756e7a61692f6c61726176656c2d63616368652d646570656e64656e63792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/lunzai/laravel-cache-dependency)[![Tests](https://camo.githubusercontent.com/03b4b210a1dc647a8e69cf90a57ac2fc726ce1004cb31cc1a0ecec469ccf3109/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6c756e7a61692f6c61726176656c2d63616368652d646570656e64656e63792f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/lunzai/laravel-cache-dependency/actions/workflows/tests.yml)[![Total Downloads](https://camo.githubusercontent.com/2d8ab6048dd9fe53e1b885b3c873a8bb4dd95517661dbc14927bac13fe2daca8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c756e7a61692f6c61726176656c2d63616368652d646570656e64656e63792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/lunzai/laravel-cache-dependency)[![License](https://camo.githubusercontent.com/ca1d2bed2407dd0bdd96550f691cb2ce51e00e579e874e0835c85d1aa2dd5828/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6c756e7a61692f6c61726176656c2d63616368652d646570656e64656e63792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/lunzai/laravel-cache-dependency)

A dependency-based caching system for Laravel inspired by Yii2. Features tag dependencies with O(1) invalidation and database dependencies for automatic cache freshness.

Why This Package?
-----------------

[](#why-this-package)

Laravel's built-in cache tags have fundamental limitations:

- **Retrieval requires exact tag match** — You must provide the exact same tags used when caching
- **Limited driver support** — Only works with Redis and Memcached
- **No database dependencies** — No automatic invalidation when data changes

This package solves all three problems.

Features
--------

[](#features)

- **Tag Dependencies:** Tags stored as metadata, retrieval without tags, O(1) invalidation via version counters
- **Database Dependencies:** Automatic cache invalidation when query results change
- **Universal Driver Support:** Works with all Laravel cache drivers (file, array, database, Redis, Memcached)
- **Cache Interoperability:** Works seamlessly with Laravel's Cache facade
- **Configurable Behavior:** Fail-open or fail-closed when database queries fail

Installation
------------

[](#installation)

```
composer require lunzai/laravel-cache-dependency
```

Optionally publish the config:

```
php artisan vendor:publish --tag="cache-dependency-config"
```

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11+

Quick Start
-----------

[](#quick-start)

```
use Lunzai\CacheDependency\Facades\CacheDependency;

// Cache with tags
CacheDependency::tags(['users', 'permissions'])
    ->put('user.1.permissions', $permissions, 3600);

// Retrieve WITHOUT tags
$permissions = CacheDependency::get('user.1.permissions');

// Invalidate — O(1) operation
CacheDependency::invalidateTags('users');
```

Tag Dependencies
----------------

[](#tag-dependencies)

### How It Works

[](#how-it-works)

Tags are stored as metadata with the cached entry. A version counter is maintained for each tag. When you invalidate a tag, the counter increments. On retrieval, cached entries check if their stored tag versions match current versions. If any tag version has increased, the cache is stale.

This is an **O(1) operation** — no iteration over cached items needed.

### Usage

[](#usage)

```
// Cache with tags
CacheDependency::tags(['user.123', 'rbac'])
    ->put('user.123.permissions', $permissions, 3600);

// Cache with multiple tags
CacheDependency::tags(['user.123', 'role.5', 'rbac'])
    ->remember('user.123.permissions', 3600, function () {
        return $this->calculatePermissions(123);
    });

// Retrieve WITHOUT specifying tags
$permissions = CacheDependency::get('user.123.permissions');

// Also works with standard Cache facade
$permissions = Cache::get('user.123.permissions');

// Invalidate all caches with 'rbac' tag (O(1) operation)
CacheDependency::invalidateTags('rbac');

// Invalidate multiple tags at once
CacheDependency::invalidateTags(['user.123', 'role.5']);

// Store indefinitely with tags
CacheDependency::tags('config')->forever('app.settings', $settings);
```

Database Dependencies
---------------------

[](#database-dependencies)

### How It Works

[](#how-it-works-1)

When caching, you provide a SQL query. The query result is stored as a "baseline". On retrieval, the query is re-executed and compared to the baseline. If they differ, the cache is stale.

### Usage

[](#usage-1)

```
// Simple DB dependency
CacheDependency::db('SELECT MAX(updated_at) FROM roles')
    ->remember('all.roles', 3600, fn() => Role::all());

// DB dependency with parameters
CacheDependency::db(
    'SELECT MAX(updated_at) FROM role_user WHERE user_id = ?',
    [$userId]
)->remember("user.{$userId}.roles", 3600, fn() => $user->roles);

// Using named connection
CacheDependency::db('SELECT COUNT(*) FROM audit_logs')
    ->connection('audit')
    ->put('audit.count', $count, 3600);
```

### Failure Handling

[](#failure-handling)

When a database query fails during cache retrieval:

- **Fail Closed (default):** Treat as cache miss, fetch fresh data
- **Fail Open:** Return cached value (prioritize availability)

Configure in `config/cache-dependency.php`:

```
'db' => [
    'fail_open' => false, // Default: fail closed
],
```

Combined Dependencies
---------------------

[](#combined-dependencies)

You can combine tags and database dependencies:

```
// Cache is invalidated if:
// - Any tag is invalidated, OR
// - DB query result changes
CacheDependency::tags(['rbac', 'permissions'])
    ->db('SELECT MAX(updated_at) FROM permissions')
    ->remember('all.permissions', 3600, fn() => Permission::all());
```

Tag Design Patterns
-------------------

[](#tag-design-patterns)

Since the package uses explicit tagging (no wildcards), proper tag design is essential:

### RBAC / Permission System

[](#rbac--permission-system)

```
// Caching user permissions
CacheDependency::tags([
    "user.{$userId}.permissions",  // Specific cache
    "user.{$userId}",              // All caches for this user
    'user.permissions',            // All user permission caches
    'rbac',                        // All RBAC-related caches
])->remember("user.{$userId}.permissions", 3600, fn() => $this->calculatePermissions($userId));

// Invalidation scenarios:
CacheDependency::invalidateTags("user.{$userId}");      // User's roles changed
CacheDependency::invalidateTags('user.permissions');    // Permission logic changed
CacheDependency::invalidateTags('rbac');                // Clear all RBAC caches
```

### E-commerce / Product Catalog

[](#e-commerce--product-catalog)

```
// Product cache
CacheDependency::tags([
    "product.{$productId}",
    "category.{$categoryId}.products",
    "vendor.{$vendorId}.products",
    'products',
])->remember("product.{$productId}", 3600, fn() => Product::find($productId));

// Invalidation:
CacheDependency::invalidateTags("product.{$productId}");           // Product updated
CacheDependency::invalidateTags("category.{$categoryId}.products"); // Category products changed
```

### Multi-tenant Application

[](#multi-tenant-application)

```
// Tenant-scoped cache
CacheDependency::tags([
    "tenant.{$tenantId}",
    "tenant.{$tenantId}.settings",
])->remember("tenant.{$tenantId}.config", 3600, fn() => $tenant->settings);

// Invalidation:
CacheDependency::invalidateTags("tenant.{$tenantId}");  // Clear all tenant caches
```

### Tag Naming Conventions

[](#tag-naming-conventions)

PatternUse CaseExample`entity.{id}`All caches for a specific entity`user.123`, `product.456``entity.{id}.aspect`Specific aspect of an entity`user.123.permissions``entity.aspect`All entities' aspect caches`user.permissions``domain`Domain-wide caches`rbac`, `products`, `settings``parent.{id}.children`Parent-child relationships`category.5.products`Configuration
-------------

[](#configuration)

Publish the configuration file:

```
php artisan vendor:publish --tag="cache-dependency-config"
```

Available options:

```
return [
    // Cache store to use (null = default)
    'store' => env('CACHE_DEPENDENCY_STORE'),

    // Prefix for internal cache keys (tag versions)
    'prefix' => env('CACHE_DEPENDENCY_PREFIX', 'cdep'),

    // Tag version TTL (should be longer than longest cache TTL)
    'tag_version_ttl' => env('CACHE_DEPENDENCY_TAG_TTL', 86400 * 30), // 30 days

    'db' => [
        // Default database connection (null = default)
        'connection' => env('CACHE_DEPENDENCY_DB_CONNECTION'),

        // Query timeout in seconds
        'timeout' => env('CACHE_DEPENDENCY_DB_TIMEOUT', 5),

        // Behavior when DB query fails:
        // - false: Return null (cache miss) - fail closed
        // - true: Return cached value (fail open)
        'fail_open' => env('CACHE_DEPENDENCY_FAIL_OPEN', false),
    ],
];
```

API Reference
-------------

[](#api-reference)

### CacheDependency Facade

[](#cachedependency-facade)

```
// Create pending dependency with tags
CacheDependency::tags(array|string $tags): PendingDependency

// Create pending dependency with DB query
CacheDependency::db(string $sql, array $params = []): PendingDependency

// Retrieve from cache
CacheDependency::get(string $key, mixed $default = null): mixed

// Store in cache (without dependencies)
CacheDependency::put(string $key, mixed $value, ?int $ttl = null): bool

// Remember pattern
CacheDependency::remember(string $key, ?int $ttl, Closure $callback): mixed

// Invalidate tags (O(1))
CacheDependency::invalidateTags(array|string $tags): void

// Get tag version
CacheDependency::getTagVersion(string $tag): int

// Check existence (checks staleness)
CacheDependency::has(string $key): bool

// Remove from cache
CacheDependency::forget(string $key): bool

// Retrieve and delete
CacheDependency::pull(string $key, mixed $default = null): mixed

// Get multiple
CacheDependency::many(array $keys): array

// Clear all
CacheDependency::flush(): bool

// Use different store
CacheDependency::store(?string $name = null): CacheDependencyManager
```

### PendingDependency Methods

[](#pendingdependency-methods)

```
// Add tags (chainable)
->tags(array|string $tags): self

// Set DB dependency (chainable)
->db(string $sql, array $params = []): self

// Set DB connection (chainable)
->connection(string $connection): self

// Store with dependencies
->put(string $key, mixed $value, ?int $ttl = null): bool

// Remember with dependencies
->remember(string $key, ?int $ttl, Closure $callback): mixed

// Store forever with dependencies
->forever(string $key, mixed $value): bool

// Store multiple with dependencies
->putMany(array $values, ?int $ttl = null): bool
```

Testing
-------

[](#testing)

```
composer test
```

Credits
-------

[](#credits)

- [HL (Lunzai)](https://github.com/lunzai)
- Inspired by [Yii2's Cache Dependencies](https://www.yiiframework.com/doc/guide/2.0/en/caching-data#cache-dependencies)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

32

—

LowBetter than 71% of packages

Maintenance75

Regular maintenance activity

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

164d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e47616fd786dc56ec35e9ceadc87d3599fc089f213c9ad73d518771eca5dc688?d=identicon)[lunzai](/maintainers/lunzai)

---

Top Contributors

[![lunzai](https://avatars.githubusercontent.com/u/1671136?v=4)](https://github.com/lunzai "lunzai (10 commits)")

---

Tags

laraveldependencycachetagsinvalidation

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/lunzai-laravel-cache-dependency/health.svg)

```
[![Health](https://phpackages.com/badges/lunzai-laravel-cache-dependency/health.svg)](https://phpackages.com/packages/lunzai-laravel-cache-dependency)
```

###  Alternatives

[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.2M51](/packages/spatie-laravel-responsecache)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[laragear/cache-query

Remember your query results using only one method. Yes, only one.

272122.8k](/packages/laragear-cache-query)[dragon-code/laravel-cache

An improved interface for working with cache

6844.8k9](/packages/dragon-code-laravel-cache)[omaralalwi/lexi-translate

Laravel translation package with morph relationships and caching.

754.3k2](/packages/omaralalwi-lexi-translate)[juampi92/laravel-query-cache

Provide easy interface for caching laravel queries

2517.2k](/packages/juampi92-laravel-query-cache)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
