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

genealabs/laravel-model-caching

A Laravel package that adds automatic query caching to Eloquent models. Use the provided trait to cache model queries, with cached results invalidated automatically when records are created, updated, or deleted, reducing database load with minimal code changes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Unchanged in shape: laravel-model-caching remains a transparent interception layer over Eloquent — cache keyed query result sets, invalidated from model events, no repository rewrite or read-model migration. It is still the right shape for read-heavy, low-write models and the wrong shape for high-write or cross-model derived state.

Two things in 13.2.0 change the architectural story materially:

  • TTL is now a first-class control surface. The new global and per-model TTL options (plus the fix that resolves TTL through eager loads and validates it at both levels) mean expiry is no longer solely a function of invalidation correctness. That converts "stale forever if invalidation misses" into "stale for bounded time," which is the single biggest reduction in this package's downside risk to date. It also gives the business a concrete number to sign off on, which the previous assessment flagged as a required but hard-to-obtain decision.
  • The key/tag format contract is now empirically confirmed as the real interface. The previous assessment called this out as unusual and risky; 13.2.0 delivers five categories of behavioural change, including changed keys, changed tags, and queries that are no longer cached at all because their keys could be shared with a query that returns different rows. That last item is the important one: it is a correctness fix, meaning earlier versions could return wrong rows from an in-package key collision, not merely stale rows from an application-level write-path gap.

Net: fit is better than before on bounded-staleness and worse than before on immediate upgrade cost.

Integration feasibility. High for a standard Laravel app on Redis, but the entry cost has risen and the upgrade gate is now the dominant line item rather than the invalidation inventory. Specifically:

  • PHP floor is 8.3. 13.2.0 drops 8.2; on 8.2 Composer pins to 13.1.11. Note that the prior assessment already listed 8.3–8.5, so verify your actual fleet PHP matrix against Composer resolution rather than trusting either document — a service that resolves to 13.1.11 will silently miss every correctness fix in this release.
  • Model-level source review is required, not optional. Two failure modes are fatal at class load, not degraded at runtime: an untyped protected $isCachable redeclaration and any trait rule naming Cachable::newBaseQueryBuilder (as or insteadof). Both are greppable and both should be a pre-merge check, because a class-load fatal is a hard outage on deploy.
  • Package identity needs verification. The release notes reference mike-bronner/laravel-model-caching where the prior assessment references genealabs/laravel-model-caching. Confirm the current Packagist name, whether the old name still resolves or is marked abandoned, and whether the namespace move changes your composer require line. A namespace/repo move is a supply-chain governance event for a TPM, not a cosmetic detail.
  • Post-deploy cache clear is a mandated step. Upgrading requires running php artisan modelCache:clear after deploy, because some changed queries retain old key text and could otherwise read entries written by the previous version. Skipping it opens a transient wrong-data window. Treat this as a deployment runbook step with an owner, not as advice.

Technical risk.

  • Correctness risk (still highest, but reshaped). Two distinct sources: (a) application write paths that don't fire model events — unchanged, still the inventory problem; (b) in-package key collisions producing wrong rows — substantially reduced by 13.2.0 items 6, but only if you are actually on 13.2.x. Running 13.1.x to avoid the breaking changes means knowingly carrying the collision class. That is a decision to make explicitly, not by inertia.
  • Upgrade risk (now realized, no longer hypothetical). This release is the concrete instance of the hazard the previous assessment predicted: key and tag formats changed, a trait method was removed, a property was typed, and a command's blast radius was narrowed. All five are defensible fixes; together they confirm a cadence where minor versions carry breaking behaviour. Plan pinning accordingly.
  • Point-release churn. 13.1.8 introduced newBaseQueryBuilder(), 13.1.11 and 13.2.0 spent multiple PRs fixing the regressions and collisions it caused. That is normal for an actively maintained package but argues against auto-upgrading across minor versions in production without a real-cache test run.
  • Abstraction risk. Unchanged and not addressable in code. Still the most common cause of hours lost to "impossible" data.
  • Maturity signals (revised). The prior "zero dependents vs 2.4k stars" mismatch is partially explained now: the changelog shows a small, named contributor set (~5 people, one first-time contributor) doing high-PR-count work, which is consistent with real but thin adoption. Positive: two external contributors landed fixes in this release, marginally improving bus factor. Negative: the maintainer authored the large majority of the PRs in a release with five breaking categories, which is a review-load concentration worth noting.
  • Metadata hygiene (resolved direction, still verify). The prior assessment flagged future-dated releases. This changelog is internally consistent and heavily cross-referenced by issue number, which is a better signal. Verify the actual version history and supported Laravel/PHP matrix in the repo rather than from this summary.

Key questions. (revised)

  1. Which cache store backs this per environment, and does it support tags? (Unchanged; Redis remains the de-risked default.)
  2. Which models are in scope, and what is the write rate and write-path inventory for each — including raw query builder, DB::table(), bulk updates, imports, and third-party jobs writing the same tables?
  3. What TTL do we set globally, and where do we override per model? TTL is now a policy decision with a business owner, not just a safety net. Decide the default and the exceptions before rollout, not per incident.
  4. Does any read path require read-your-writes within a request, and do we need a request-scoped bypass?
  5. Are we on PHP 8.3+ everywhere this package runs, and do all services resolve to 13.2.x rather than 13.1.11?
  6. Have we audited every model for untyped $isCachable and for trait rules naming Cachable::newBaseQueryBuilder? Both are class-load fatals.
  7. What is the pinned version policy — exact pin, ~13.2.0, or ^13.0? Given that minor versions have carried breaking changes, what is our justification for anything looser than a tilde?
  8. How many Laravel majors are in the fleet, and how do we test against each with a real cache store?
  9. Is genealabs/laravel-model-caching → mike-bronner/laravel-model-caching a rename we need to action, and is there a maintained succession plan if upstream goes quiet?

Integration Approach

Stack fit. Unchanged: Laravel (multiple majors CI-tested), now PHP 8.3–8.5, tag-capable cache store with Redis as the de-risked default. Library, not a service — composer require, no runtime process, no schema change. 13.2.0 adds a configuration surface (global + per-model TTL) that fits naturally into existing config files rather than requiring code changes.

Migration path. Still incremental and reversible, but there are now two paths and they should not be conflated:

Path A — new adoption. Unchanged from the prior assessment, and strictly better than before because you start on 13.2.x with TTL available:

  1. Install 13.2.x pinned (~13.2.0), caching disabled globally, cache store pointed at Redis.
  2. Establish the global TTL default and the staleness sign-off.
  3. Enable for one low-risk, read-heavy model. Instrument hit/miss, invalidation, and expiry counts.
  4. Expand model by model, each change individually revertable.
  5. Enable broadly only after the invalidation inventory closes.

Path B — existing install upgrading. This is now the higher-risk path and needs its own runbook:

  1. Grep the codebase for untyped $isCachable declarations and for Cachable::newBaseQueryBuilder in as/insteadof rules. Fix before upgrade — these are class-load fatals.
  2. Confirm PHP 8.3+ on every service, and confirm Composer resolves to 13.2.x rather than pinning back to 13.1.11.
  3. Deploy with caching enabled but expect a partial cold cache; schedule the window.
  4. Run php artisan modelCache:clear immediately post-deploy. Do not skip; do not substitute cache:clear.
  5. Update any script or runbook that used modelCache:clear as a general "flush everything" — that behaviour is gone. Add php artisan cache:clear where whole-store flushing was actually intended.
  6. Review cooldown-dependent behaviour on models declaring $cachePrefix: an open cool-down window ends early once at upgrade.
  7. Re-baseline hit ratio before and after; expect a dip that recovers.

There is still no big-bang migration and none should be attempted. Rollback per model remains a config flag.

Compatibility. Four axes to verify explicitly now, up from two:

  • PHP floor (new). 8.3+ required by 13.2.0; 8.2 pins to 13.1.11. This is the first thing to check in a multi-service fleet because Composer will "succeed" while leaving you on an older, less correct version.
  • Laravel major. Unchanged — pin and test, don't assume.
  • Cache driver. Tags require Redis/Memcached; file and database stores do not support them.
  • Trait composition. Models that combine Cachable with CTE or other traits defining newBaseQueryBuilder() are the specific population at risk from item 3. Enumerate them.

Also confirm behaviour under queue workers, Octane/long-lived workers, and multi-tenant setups where keys must not collide across tenants — the $cachePrefix cooldown-key change in this release makes the multi-tenant path worth an explicit test. Testing approach: mirror the project's own pattern — Testbench plus a live Redis and Pest — because an array store masks tag and serialization behaviour and would have caught none of the bugs this release fixed.

Sequencing. (revised — step 0 is new and blocks everything) 0. Upgrade gate: PHP floor verification, $isCachable and trait-rule audit, pinned version decided, modelCache:clear added to the deploy runbook.

  1. Invalidation inventory and per-model staleness/TTL sign-off (business + engineering jointly).
  2. Redis provisioning, capacity, and eviction policy review — must not be noeviction on a store shared with queues/sessions.
  3. Install/upgrade, configure, enable for pilot model.
  4. Observability: hit ratio, invalidation volume, expiry volume, and a per-request cache bypass.
  5. Phased model rollout.
  6. Upgrade/pin policy documented in the dependency review checklist, with an explicit note that this package's minor versions have historically carried breaking changes.

For existing installs, step 0 comes before step 1, because the audit results may change scope.

Operational Impact

Maintenance. Code-maintenance surface stays low; process maintenance goes up. The ongoing obligations are now three rather than two:

  • (a) Every Laravel major upgrade is evaluated against this dependency first.
  • (b) Every schema or write-path change that bypasses Eloquent needs a cache-invalidation review — add it to the definition of done for data-layer changes, or it will be skipped.
  • (c) New: every minor-version upgrade is treated as potentially breaking. Read the changelog as a breaking-change document, run the class-load audit, and execute the post-deploy cache clear. 13.2.0 is the reference case.

TTL partially relieves (b) by bounding the damage of a missed invalidation, but it does not remove the obligation — it converts a potential indefinite staleness incident into a shorter one.

Support. Still a single-maintainer project, now with a slightly better contributor base (two external contributors in this release, one first-time). The contribution discipline visible in the changelog — issue-first, numbered review points resolved in follow-up PRs, explicit regressions tracked — remains a genuinely strong signal for a package this size. Two offsets: bus factor is still one, and the release shows the package is willing to make breaking behavioural changes in a minor version, which raises the cost of being wrong about a fork. Budget for internal vendoring and name an internal owner; there is no commercial support path.

Scaling. Unchanged core story — Redis becomes a hard dependency on the read path, capacity must cover the hot working set plus headroom, and cache flush causes stampede. 13.2.0 improves two things and worsens one:

  • Better: per-model TTL gives a natural bound on resident memory for high-cardinality models, where tag-index growth was previously unbounded between invalidations. Use TTL deliberately as a memory control, not only a staleness control.
  • Better: narrowing modelCache:clear from "wipe the whole Redis database when the prefix is empty" to "delete only this package's entries" removes a genuinely dangerous blast radius — particularly on a Redis instance shared with sessions and queues.
  • Worse: the mandatory post-deploy modelCache:clear guarantees a deliberate cold-cache event on the upgrade deploy. Coordinate it with traffic levels, warm the hot set if you can, and stagger across instances. This is now a scheduled database-load event, not an incidental one.

Failure modes. Rehearse these; each needs a named owner and a detection signal before rollout.

  • Silent staleness from non-Eloquent writes. Unchanged; highest severity, lowest detectability. TTL now bounds it — set it.
  • Partial cold cache on upgrade. Some keys change and keep old text simultaneously, so without the post-deploy clear you can read entries written by the previous version. Wrong data, no error.
  • Class-load fatal on deploy. Untyped $isCachable or a stale Cachable::newBaseQueryBuilder trait rule. High severity, high detectability, cheap to prevent — grep in CI.
  • Version pin-back. A service on PHP 8.2 silently stays on 13.1.11 and carries the key-collision correctness bugs this release fixes. Detectable in CI by asserting the resolved version, not the constraint.
  • Runbook breakage. Automation calling modelCache:clear expecting a full flush now under-flushes. Symptom is a "stuck" cache after a manual intervention. Low severity, confusing.
  • Invalidation over-reach / hit-ratio collapse. A broad tag causes excessive flushing.
  • Redis outage. Latency cliff or hard failure depending on fail-open/fail-closed posture — decide explicitly.
  • Phantom debugging. Caching is invisible; engineers lose hours. TTL does not help here.
  • Tenant bleed. Key collisions across tenants; re-verify given the $cachePrefix cooldown-key change.

Ramp-up. Roughly a day for an experienced Laravel engineer to install 13.2.x and get a pilot model working with TTL configured. One to three weeks for the team to build the invalidation inventory, wire observability, and roll out the first cohort responsibly. For an existing install, add one to two days for the audit, the trait-composition check, the modelCache:clear runbook change, and a scheduled cold-cache deploy window.

The organizational ramp-up remains the longer and more important half: teaching the team that reads may be cached, and adding cache-invalidation review to the change process. Now add a third habit: read this package's changelog as breaking-changes-only, and never take a minor bump on a Friday. Write the two or three paragraphs of internal documentation covering which models are cached, what the TTL policy is, and how to bypass the cache when debugging. Absent that, expect repeated incidents that look like application bugs — and now also expect at least one upgrade deploy where someone skips the cache clear.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource