rinvex/cacheable
Rinvex Cacheable adds automatic query caching to Laravel Eloquent models through a simple drop-in trait. It supports cache tags, configurable TTL, and smart invalidation on create, update, and delete, reducing database load with no extra code.
Architecture fit. Rinvex Cacheable is a trait-plus-builder package: adding Cacheable to a model causes newEloquentBuilder() to return a wrapped builder that intercepts get(), first(), find(), paginate() and friends, checks a taggable cache store, and returns a CacheableCollection that re-queries only the IDs that missed. It hooks Eloquent's saved/deleted events to flush the model's tag. For a conventional Laravel monolith with read-heavy, low-write models (taxonomies, catalogs, settings, CMS content), the fit is genuinely good — the integration surface is one trait and one config file, and application code stays unchanged. It is a poor fit for anything with multi-tenant cache key scoping, read/write splits, or writes that bypass Eloquent, because invalidation is only as reliable as the event coverage.
Integration feasibility. Nominal effort is under a day: composer require, add the trait, publish config/cacheable.php, set a default TTL. The hard dependency is a tag-capable cache store — Redis, Memcached, or array. File and database drivers silently cannot tag, so the package is unusable on the default file cache, which is the most common dev and small-production configuration. That constraint should be validated before any pilot.
Technical risk. The dominant risk is not the code, it is the lifecycle: the package is archived and explicitly marked abandoned. That means no security patches, no PHP 8.x/Laravel 9+ compatibility work, no upstream triage, and no upgrade path when Illuminate\Database\Eloquent\Collection or builder internals change. Secondary risks are correctness-shaped and silent: invalidation does not fire for DB::table() writes, Model::where(...)->update() query-builder mass updates, raw SQL, or changes to related models that are embedded in a cached parent. These produce stale reads that surface as data-integrity bugs weeks later, not as exceptions. Third: tag-based invalidation on Redis means a tag flush can be O(n) in the number of tagged keys, which is a real latency cliff on high-cardinality models.
Key questions.
upsert, raw SQL, another service on the same DB)?spatie/laravel-model-caching) before committing to a fork?Stack fit. Realistically Laravel 6–8 on PHP 7.3/7.4, with Redis as the cache backend. On Laravel 9+ expect friction: the package predates the Enumerable/Collection contract tightening and the model-factory namespace move, and its composer.json constraints will block installation outright. Treat "does it install on our Laravel version" as the first gate, not a later surprise.
Migration path. Three viable routes, in preference order:
spatie/laravel-model-caching (actively maintained, same tag-based automatic-invalidation model, same trait-on-model ergonomics). This is the default recommendation; the conceptual migration is nearly mechanical because the architecture and caveats are identical.illuminate/* and PHP constraints, add regression tests around invalidation edge cases. Budget 1–2 engineer-days for the fork plus compatibility work, and 1–2 days per quarter thereafter.Compatibility. Verify three things concretely: the illuminate/support and illuminate/database version constraints in composer.json; that the target cache driver implements Illuminate\Contracts\Cache\TaggableStore; and that CacheableCollection still satisfies whatever Collection methods the application calls (pagination, serialization, toArray, map chains). If a fork is chosen, add a test that asserts invalidation on create/update/delete/restore for at least one model.
Sequencing.
Maintenance. Upstream maintenance is zero by definition. Every Laravel or PHP upgrade becomes our problem, and the failure mode is a blocked framework upgrade rather than a broken feature — which is worse, because it silently accrues architectural debt. Fork ownership must be explicit and resourced; an unowned fork is the worst outcome of all three routes.
Support. No upstream issue triage, no CVE response, no maintainer to escalate to. MIT licensing makes forking legally clean and the code is small enough (~a handful of classes) to audit fully in an afternoon — that audit is the mitigation, and it should happen before adoption, not after.
Scaling. Three pressure points. (1) Tag cardinality: one tag per model class is coarse — every write to any row invalidates all cached queries for that model, so write-heavy models get near-zero hit rates and pure overhead. (2) Redis memory and hot keys: tag sets grow with distinct query keys; on Redis Cluster, tag maintenance concentrates on a single slot. (3) Cold-start stampede: after a deploy or flush, concurrent requests all miss and hit the DB simultaneously — needs a lock/Cache::lock or jittered TTL, which the package does not provide.
Failure modes.
upsert, and adjacent services on the same database all bypass invalidation.CACHE_PREFIX per environment causing staging data to serve in production.Ramp-up. Developer ramp-up is genuinely low — half a day, since the API is transparent and requires no call-site changes. The real ramp-up is organizational: the team must internalize and enforce the invalidation invariants (no query-builder writes to cached models, no cross-model assumptions, TTL as a correctness backstop not a performance knob). Budget for a short internal design note and a code-review checklist; without that, the package's convenience becomes the mechanism by which stale data reaches users.
Verdict. The design is sound and the ergonomics are good, but the archived status converts a low-effort integration into a permanent ownership liability. Recommend substituting the maintained equivalent; if the API shape is specifically desired, fork with a named owner and a scheduled compatibility review. Do not adopt as-is for anything with a multi-year lifetime.
How can I help you explore Laravel packages today?