Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Model Caching Laravel Package

mike-bronner/laravel-model-caching

Automatic query caching for Laravel Eloquent models. Cache query results and relationships, then invalidate cached data automatically when models change, reducing database load and speeding up repeated reads with minimal code changes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Unchanged in kind: mike-bronner/laravel-model-caching remains a drop-in Eloquent optimization, not an architectural component. Two things in 13.2.0 move the boundary of where it fits, though. First, global and per-model TTL caching (PR #637) removes one of the previous disqualifiers — "anything where per-query TTL control matters" — because a model can now be given a bounded staleness window that acts as a backstop under the event-based invalidation. That widens eligibility from "read-heavy, low-churn reference data" to "read-heavy models with a defensible staleness SLA," but it does not make write-heavy models or read-after-write-consistent paths suitable. Second, the invalidation fixes (pivot-table tagging, where-subquery joined-table tagging, morphTo memoization, macro-argument keying) materially improve correctness on relationship-heavy models, which were previously the fragile case. Design-review posture stays the same: a latency/DB-load lever, admitted per model, never a blanket default.

Integration feasibility. Install effort is still low (one Composer dependency, one trait per model); upgrade effort is now a real line item rather than a version bump, and 13.2.0 is a good demonstration of why. Four upgrade hazards are worth naming:

  • PHP 8.3 floor. 8.2 is dropped; Composer will silently hold teams on 13.1.11 unless the runtime is upgraded. This makes the package a driver of the PHP upgrade, not a passenger on it.
  • protected bool $isCachable. Any model or builder redeclaring this untyped now fatals at class load. Loud and immediate, which is the good failure mode — but it must be grep'd across the codebase before deploying.
  • newBaseQueryBuilder() removed from the trait. This is the collision class we flagged as a secondary risk, and it materialized: a method added in 13.1.8 collided with CTE-style traits and was pulled two patches later. Any local trait rule naming Cachable::newBaseQueryBuilder now fatals. Teams that patched around the collision must revert their workaround.
  • modelCache:clear no longer empties the whole cache store. Blast radius is reduced (and this closes a genuine footgun where an empty prefix wiped an entire Redis database), but any operational script using it as a general flush must add php artisan cache:clear. Additionally, the release changes many cache keys and tags, so a one-time cold cache for those query shapes should be assumed. That is a deploy-day capacity event, not a code risk, and belongs in the rollout runbook.

Technical risk. The headline risk has shifted from "coupling to internals" in the abstract to demonstrated churn in builder internals: a method was introduced in 13.1.8 and removed in 13.2.0, with regressions shipped in 13.1.11 and fixed across #640/#651. Treat exact-version pinning and staged upgrades as mandatory controls, not hygiene. Separately, several fixes in this release close silent wrong-row bugs, not merely staleness: macro and custom-builder-method arguments previously shared cache keys across null/false/"" and 1/"1", and several query shapes reused keys they should not have. That means versions below 13.2.0 could return incorrect results, not just old ones, on codebases using macros, closure where() on globally-scoped models, or eager-loaded many-to-many relations. Recommendation: adopt 13.2.0 as the floor, and treat any existing deployment on 13.1.x as carrying a correctness defect rather than a performance-tuning gap. Residual risks are unchanged: builder decoration conflict with other packages, unbounded key cardinality in Redis, and coarse per-model invalidation. Note the release notes also state that the README's "What Does Not Get Cached" section was wrong about lazy loads and select() — so documentation is not a reliable specification; verify caching behaviour per code path against the code.

Key questions for the team.

  1. What is the read/write ratio and acceptable staleness window per candidate model — and with TTL now available, what is the number we set per model, and who signs off on it?
  2. Are we on PHP 8.3+ in all environments, including CI and queue workers, or does 13.2.0 hold us at 13.1.11?
  3. Which cache store, and is tag support confirmed in the target environment (including Redis Cluster, where Laravel's tag implementation has known limitations)?
  4. Do any models declare $isCachable, or any trait rules reference Cachable::newBaseQueryBuilder? Both now fatal at class load.
  5. Does any operational script or runbook rely on modelCache:clear flushing the entire store?
  6. Do candidate models use macros, custom builder methods, closure where() under global scopes, or eager-loaded many-to-many relations? If so, we are currently exposed to key-collision bugs and must upgrade before, not after, piloting.
  7. Does any code path write to candidate tables outside Eloquent — imports, seeders, raw SQL, queue jobs, analytics pipelines? Each remains a permanent-staleness vector, now mitigated by TTL but not eliminated.
  8. Multi-tenancy: are cache keys namespaced per tenant?
  9. How is caching disabled in tests and local dev?

Integration Approach

Stack fit. Laravel with Eloquent, PHP 8.3+, and a tag-capable cache backend — Redis (phpredis/predis) preferred, Memcached viable with key-size and eviction caveats. Compatible with horizontal app scaling and queue workers provided invalidation shares the cache namespace. Confirm Octane behaviour explicitly if the platform runs it. The CTE/trait-collision conflict is resolved by this release, but verify against whatever else decorates the Eloquent builder in our tree — Scout, auditing, soft-delete extensions — since trait ordering still matters.

Migration path. Incremental and reversible, but now front-loaded with an upgrade rather than starting from a clean install:

  • Upgrade to 13.2.0 first, before any pilot. The correctness fixes are the reason; piloting on 13.1.x would validate behaviour we do not intend to ship.
  • Complete the pre-upgrade grep: untyped $isCachable declarations, trait rules naming Cachable::newBaseQueryBuilder, and scripts relying on modelCache:clear clearing everything.
  • Provision/confirm a Redis cache store with an eviction policy and a memory budget sized for key cardinality, not data size.
  • Pilot on one or two read-heavy models. Set a per-model TTL from the outset — do not run without one, even where invalidation is believed to be sufficient.
  • Establish a documented escape hatch (disableCache() per query, or a repository-level Cache::remember) so teams are never blocked by package behaviour.

Compatibility. Rebuild the version matrix from scratch: PHP 8.3/8.4, Laravel major, cache driver, and every package touching the Eloquent builder. Test trait ordering where multiple traits apply to one model. Explicitly exercise the historically fragile paths — soft deletes, global scopes, whereHas subqueries, inRandomOrder, cursor()/chunk(), pagination counts, belongsToMany/morphToMany with withPivot()/withTimestamps()/custom as(), macro calls with arguments, and fromSub()/union bindings — because several of these changed key text or moved to uncached in this release.

Sequencing. (1) Runtime upgrade to PHP 8.3 and package upgrade to 13.2.0 on a branch, with the grep checklist and a full test pass; (2) one-sprint PoC on a single model with load-test comparison and a TTL set; (3) cache infrastructure and observability — hit rate, miss rate, invalidation rate, Redis memory; (4) production pilot behind a feature flag, deployed with php artisan modelCache:clear followed by deliberate cache warming, since the key changes guarantee a cold start; (5) broaden with per-model staleness sign-off; (6) publish an internal standard on eligible models, TTL conventions, bypass mechanism, forbidden write patterns, and the upgrade/pinning policy. Do not sequence this before the cache store is production-hardened.

Operational Impact

Maintenance. The maintenance picture is modestly better than the prior assessment: an active release with many substantive contributor PRs, a first-time contributor, and a maintainer resolving detailed review feedback within the cycle. That is a healthy signal. It is, however, a double-edged one — the velocity also produced a method added and removed inside a minor version, plus regressions that shipped and were then corrected. The correct operational response is to pin to an exact patch, upgrade deliberately with the checklist above, and retain the internal capability to fork and patch. Assign a named owner; packages with subtle invalidation semantics rot silently when ownership is diffuse.

Support. Still no vendor SLA; GitHub issues and community write-ups are the support surface. Responsiveness in this release cycle is encouraging, but community support cannot be scheduled against an incident. Keep the internal fork contingency budgeted.

Scaling. DB read reduction on the right models remains the payoff, and TTL support improves the economics: bounded staleness, a natural cap on how long a bad key can survive, and a safety net for any write path we missed. Costs still shift to Redis — key cardinality grows with query diversity, not data size — and TTL adds expiry churn without reducing cardinality. Coarse per-model invalidation is unchanged: one write to a hot table flushes the whole working set and can stampede the database. Mitigations: cache warming, TTL jitter, request coalescing on the hottest paths, and no trait on bursty-write models. New scaling consideration: every upgrade that changes key text creates a synchronized cold cache across the fleet — plan upgrades as capacity events, not just deploys.

Failure modes to design for.

  • Upgrade-induced cold cache. Changed keys mean the first requests after deploy all miss. Mitigate with post-deploy warming and a staged rollout; monitor DB CPU at deploy time, not just steady state.
  • Fatal error at class load from an untyped $isCachable or a stale Cachable::newBaseQueryBuilder trait rule. High-severity but immediate and obvious; catch it in CI by loading every model class.
  • Silent permanent staleness from writes bypassing Eloquent (raw SQL, mass updates, importers, external services). Still the highest-severity, lowest-visibility failure — now mitigated, not solved, by mandatory per-model TTLs. Add CI/review checks against raw writes to cached tables.
  • Wrong rows from cache-key collisions on versions below 13.2.0 for macro/custom-builder calls, scoped closure where(), and many-to-many eager loads. Treat as a correctness defect in current deployments and remediate by upgrading.
  • Cache store outage or eviction storm — confirm whether the package degrades gracefully or throws, and put a fallback-to-DB path in place.
  • Stampede after invalidation on high-traffic models, presenting as latency spikes and DB CPU alarms correlated with writes.
  • Stale pagination/total counts surfacing as user-visible bugs in list and API pagination.
  • Cross-tenant leakage if keys are not tenant-scoped on a shared store — correctness and compliance, not performance.
  • Ops scripts silently under-flushing now that modelCache:clear is scoped to package entries; audit any runbook that assumed a full-store wipe.

Ramp-up. Developer ramp-up is still near zero (one trait line), which remains the trap. The onboarding item now has three clauses instead of one: "any write outside Eloquent invalidates nothing," "every cached model carries an explicit TTL and a named staleness owner," and "upgrades are pinned, staged, and include a cache clear plus warm." One to two days for a senior engineer to be productive; the real investment is standing ownership, the upgrade runbook, and the fork contingency. Net: adoptable as a targeted optimization with clear per-model admission criteria — and now, with TTL and the correctness fixes in place, a more defensible bet than the prior release line, provided 13.2.0 is the floor and PHP 8.3 is on the roadmap.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox