PHPackages                             foxws/laravel-modelcache - 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. [Database &amp; ORM](/categories/database)
4. /
5. foxws/laravel-modelcache

ActiveLibrary[Database &amp; ORM](/categories/database)

foxws/laravel-modelcache
========================

Cache helpers for Laravel Eloquent models

1.4.1(2mo ago)25.9k[1 PRs](https://github.com/foxws/laravel-modelcache/pulls)MITPHPPHP ^8.2CI passing

Since Oct 28Pushed 1w ago1 watchersCompare

[ Source](https://github.com/foxws/laravel-modelcache)[ Packagist](https://packagist.org/packages/foxws/laravel-modelcache)[ Docs](https://github.com/foxws/laravel-modelcache)[ GitHub Sponsors](https://github.com/Foxws)[ RSS](/packages/foxws-laravel-modelcache/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (45)Versions (17)Used By (0)

Laravel model cache helper
==========================

[](#laravel-model-cache-helper)

[![Latest Version on Packagist](https://camo.githubusercontent.com/9aab1b649871aa61830cbf64c38c8032c829ebb0defdc3fe0f90b23277175cb7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f666f7877732f6c61726176656c2d6d6f64656c63616368652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/foxws/laravel-modelcache)[![GitHub Tests Action Status](https://camo.githubusercontent.com/0babfdbac8c1c5f4c856736c245639951a336a786c02061eb83aa5153235437e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f666f7877732f6c61726176656c2d6d6f64656c63616368652f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/foxws/laravel-modelcache/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/023350db213ec95fd735d90e4e0a62b08b439cf89d14d0527182b231953807e2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f666f7877732f6c61726176656c2d6d6f64656c63616368652f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/foxws/laravel-modelcache/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/b2ae0f6da0aedca6ec9c81c34f43d089fbf208577478d0acba28591ecb1ac0bc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f666f7877732f6c61726176656c2d6d6f64656c63616368652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/foxws/laravel-modelcache)

Attach arbitrary cached values to Eloquent model instances or classes using any Laravel cache driver. By default each authenticated user gets an isolated cache namespace, so two users never share the same cached value for the same model.

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

[](#installation)

Install the package via Composer:

```
composer require foxws/laravel-modelcache
```

Optionally publish the config file:

```
php artisan vendor:publish --tag="modelcache-config"
```

### Environment variables

[](#environment-variables)

VariableDefaultDescription`MODEL_CACHE_ENABLED``true`Toggle caching on/off globally`MODEL_CACHE_STORE``CACHE_STORE`Cache store to use (any store from `config/cache.php`)`MODEL_CACHE_LIFETIME``604800` (1 week)Default TTL in secondsUsage
-----

[](#usage)

### 1. Add the trait to your model

[](#1-add-the-trait-to-your-model)

```
use Foxws\ModelCache\Concerns\InteractsWithModelCache;
use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    use InteractsWithModelCache;
}
```

That is all the setup required. Every public method below becomes available on the model.

---

### 2. Instance cache

[](#2-instance-cache)

These methods are scoped to a specific model record (e.g. `Video` with `id = 5`).

**Store a value:**

```
$video = Video::findOrFail(5);

$video->modelCache('playback_position', 142);

// With a custom TTL
$video->modelCache('random_seed', 0.73, now()->addHours(6));
$video->modelCache('last_viewed', now(), 3600); // TTL as seconds
```

**Retrieve a value:**

```
$position = $video->modelCached('playback_position');        // null if not cached
$seed     = $video->modelCached('random_seed', 0.5);         // 0.5 as fallback
```

**Check existence:**

```
if (! $video->modelCacheHas('playback_position')) {
    $video->modelCache('playback_position', 0);
}
```

**Forget a value:**

```
$video->modelCacheForget('playback_position');
```

**Remember a value (fetch or store):**

`modelCacheRemember` returns the cached value if it exists, otherwise resolves the closure (or uses the plain value), stores it, and returns it.

```
// With a closure (recommended for expensive operations)
$stats = $video->modelCacheRemember('stats', fn() => $this->computeExpensiveStats($video), now()->addDay());

// With a plain value
$video->modelCacheRemember('random_seed', 0.73, now()->addHours(6));
```

**Practical example — lazy-load an expensive computed value:**

```
class VideoController extends Controller
{
    public function show(Video $video): JsonResponse
    {
        $stats = $video->modelCacheRemember('stats', fn() => $this->computeExpensiveStats($video), now()->addDay());

        return response()->json($stats);
    }
}
```

---

### 3. Class cache (global)

[](#3-class-cache-global)

These static methods are scoped to the model *class* rather than a specific record. Useful for values shared across all instances, such as global seeds or configuration.

**Store a value:**

```
Video::setModelCache('random_seed', 0.42);
Video::setModelCache('random_seed', 0.42, now()->addWeek());
```

**Retrieve a value:**

```
$seed = Video::getModelCache('random_seed');          // null if not cached
$seed = Video::getModelCache('random_seed', 0.5);     // with fallback
```

**Check existence:**

```
if (! Video::hasModelCache('random_seed')) {
    Video::setModelCache('random_seed', rand() / getrandmax());
}
```

**Forget a value:**

```
Video::forgetModelCache('random_seed');
```

---

### 4. Facade

[](#4-facade)

Use the `ModelCache` facade when you need to interact with caching outside of a model — for example in an action class or a service.

```
use Foxws\ModelCache\Facades\ModelCache;

class RecordPlaybackPosition
{
    public function handle(Video $video, int $seconds): void
    {
        if (! ModelCache::enabled()) {
            return;
        }

        if (! ModelCache::shouldCache($video, 'playback_position', $seconds)) {
            return;
        }

        ModelCache::cache($video, 'playback_position', $seconds, now()->addDay());
    }
}
```

```
// Read from cache
$position = ModelCache::getCachedValue($video, 'playback_position');

// Check
$exists = ModelCache::hasBeenCached($video, 'playback_position');

// Forget one or multiple keys
ModelCache::forget($video, 'playback_position');
ModelCache::forget($video, ['playback_position', 'random_seed']);
```

---

### 5. Controlling which values get cached (`shouldModelCache`)

[](#5-controlling-which-values-get-cached-shouldmodelcache)

Override `shouldModelCache` on the model to conditionally skip caching certain keys or values:

```
class Video extends Model
{
    use InteractsWithModelCache;

    public function shouldModelCache(string $key, mixed $value = null): bool
    {
        // Never cache a null value
        if ($value === null) {
            return false;
        }

        // Only cache specific keys
        if (! in_array($key, ['playback_position', 'random_seed', 'stats'])) {
            return false;
        }

        return true;
    }
}
```

---

### 6. Custom cache profile

[](#6-custom-cache-profile)

A cache profile controls global caching behaviour: whether caching is enabled, when values expire, and which per-user namespace suffix to use. The default is `CacheAllSuccessful`, which caches all values for all users.

Create your own by implementing `CacheProfile`:

```
use Foxws\ModelCache\CacheProfiles\BaseCacheProfile;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

class AuthenticatedUserCacheProfile extends BaseCacheProfile
{
    public function shouldUseCache(Model $model, string $key): bool
    {
        // Only cache for authenticated users
        return Auth::check();
    }

    public function shouldCacheValue(mixed $value = null): bool
    {
        // Do not cache null or empty strings
        return $value !== null && $value !== '';
    }
}
```

Register it in `config/modelcache.php`:

```
'cache_profile' => AuthenticatedUserCacheProfile::class,
```

---

### 7. Per-model cache namespace (`cacheNameSuffix`)

[](#7-per-model-cache-namespace-cachenamesuffix)

By default, `BaseCacheProfile::useCacheNameSuffix` returns the authenticated user's ID, isolating each user's cache. You can override this per model:

```
class Video extends Model
{
    use InteractsWithModelCache;

    protected function cacheNameSuffix(string $key): string
    {
        // Shared cache regardless of who is logged in
        return '';
    }
}
```

```
class Post extends Model
{
    use InteractsWithModelCache;

    protected function cacheNameSuffix(string $key): string
    {
        // Separate cache per user
        return Auth::check() ? (string) Auth::id() : '';
    }
}
```

```
class Report extends Model
{
    use InteractsWithModelCache;

    protected function cacheNameSuffix(string $key): string
    {
        // Separate cache per key type, shared across users
        return $key;
    }
}
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

This package is heavily inspired by and based on the [spatie/laravel-responsecache](https://github.com/spatie/laravel-responsecache/) package by [Spatie](https://spatie.be).

If you find their work valuable, please consider [sponsoring Spatie](https://spatie.be/open-source/support-us) or purchasing one of their [courses and products](https://spatie.be/products).

License
-------

[](#license)

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

###  Health Score

51

—

FairBetter than 95% of packages

Maintenance92

Actively maintained with recent releases

Popularity27

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 77% 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

Every ~53 days

Recently: every ~89 days

Total

11

Last Release

80d ago

Major Versions

0.0.4 → 1.0.02024-12-27

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5028905?v=4)[François M.](/maintainers/francoism90)[@francoism90](https://github.com/francoism90)

---

Top Contributors

[![francoism90](https://avatars.githubusercontent.com/u/5028905?v=4)](https://github.com/francoism90 "francoism90 (47 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (6 commits)")

---

Tags

cachecachingeloquentfoxwshelperlaravellaravel-packagemodelsredislaravelmodeleloquentcachecachingmodelslaravel-modelcache

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/foxws-laravel-modelcache/health.svg)

```
[![Health](https://phpackages.com/badges/foxws-laravel-modelcache/health.svg)](https://phpackages.com/packages/foxws-laravel-modelcache)
```

###  Alternatives

[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k9.0M69](/packages/spatie-laravel-responsecache)[propaganistas/laravel-disposable-email

Disposable email validator

6023.0M7](/packages/propaganistas-laravel-disposable-email)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M194](/packages/laravel-ai)[laravel/sail

Docker files for running a basic Laravel application.

1.9k205.7M1.3k](/packages/laravel-sail)[laravel/pulse

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

1.7k15.1M132](/packages/laravel-pulse)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

44855.7k](/packages/harris21-laravel-fuse)

PHPackages © 2026

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