morilog/infinity-cache
Infinity Cache for Laravel makes it easy to cache expensive Eloquent query results and keep them fresh: cached data is automatically invalidated when the underlying models change, so you get the speed of caching without stale reads or manual cache-busting code.
Architecture fit. morilog/infinity-cache is a model-layer, transparent query-cache: it sits between the Eloquent builder and the cache store, keyed presumably on generated SQL plus bindings, with invalidation wired to model lifecycle events (saved, deleted, restored). Architecturally that is the right shape for a read-heavy Laravel app — no controller-level Cache::remember sprawl, and invalidation lives next to the write path. The problem is vintage, not design. The last release is February 2016, which places it squarely in the Laravel 5.1/5.2 era: manual service-provider registration in config/app.php (package auto-discovery did not exist until 5.5), PHP 5.5/5.6 syntax, and pre-Illuminate\Support\Str-v2 helper conventions. On Laravel 9/10/11 the code is likely readable but not installable as-is. Treat it as an architecture reference, not a dependency.
Integration feasibility. Composer is the first gate and it fails hard. A 2016 composer.json will pin illuminate/support and illuminate/database to 5.*, so composer require morilog/infinity-cache against a modern app errors out before any code loads. Circumventing that with --ignore-platform-reqs or a forked constraint set only buys you a runtime failure surface: Illuminate\Database\Eloquent\Builder internals, global scope registration, and cache repository contracts have all shifted. The realistic paths are (a) fork into app/Packages/ or a private VCS repo with updated constraints and tests, or (b) reimplement the 150–300 line pattern natively. Given 31 stars, zero dependents, and no maintainer activity in roughly a decade, (b) is the defensible default.
Technical risk.
Model::where(...)->update() mass update (events bypassed), a raw DB::statement, or a write from a queue worker or sibling service produces stale reads with no signal.Key questions.
file/database stores where tags are unsupported?withCount subqueries attributed to models for busting?upsert, raw statements, and soft-delete restore()?Post write invalidating a User->posts query)?Stack fit. The package assumes Laravel 5.x, PHP 5.5–7.0, and a cache store that either supports tags (Redis/Memcached) or tolerates a tag-emulation fallback. It has no place in a Laravel 10/11 codebase without modification, and no place at all in a multi-service architecture where other writers touch the same tables.
Migration path. Two viable routes, in preference order:
| Route | Effort | Risk | Verdict |
|---|---|---|---|
Reimplement pattern natively in app/Caching/ |
3–5 dev days incl. tests | Low, fully owned | Recommended |
| Fork to private repo, bump constraints, add tests | 5–8 dev days | Medium, inherits unknown semantics | Acceptable if parity is proven |
Adopt maintained equivalent (genealabs/laravel-model-caching) |
2–3 dev days | Low–medium, active upstream | Strong alternative |
| Install as-is with ignored platform reqs | 1 hour | High, unsupported | Reject |
If the goal is purely to learn the invalidation model, read the source and port it. If the goal is production caching on a schedule, take a maintained package with a tag-based invalidation story you can reason about, or build the thin native version and own it.
Compatibility. Verify explicitly before committing to any route: PHP version and strict-types behavior, Laravel's Builder/Model event surface, cache store capabilities (tags require Redis or Memcached — file and database do not support them), and whether the app runs under Octane or Horizon where long-lived workers change the invalidation timing assumptions.
Sequencing.
QueryCache contract) so the store and strategy are swappable.Maintenance. Adopting the package means adopting a fork. That is a permanent, low-volume but non-zero tax: every Laravel major upgrade requires re-validating the fork against new builder internals, and there is no upstream to lean on. Owning ~200 lines of native code is cheaper over a three-year horizon than owning a vendored 2016 fork.
Support. Effectively none. No maintainer activity since 2016, no issue triage, no security response channel, MIT with no warranty. Any production incident traces back to your team. Budget for that explicitly — it is the single strongest argument against adoption.
Scaling. Cache effectiveness is entirely store-dependent. Redis with tags scales well but requires memory planning; a no-TTL "infinity" policy without eviction discipline turns Redis into an OOM risk under key cardinality growth (every distinct binding combination is a key). Plan: bounded TTL as a backstop even if invalidation is event-driven, hit-rate dashboards, and a per-model key-count alarm.
Failure modes, ranked by severity:
Ramp-up. The code is small enough that a mid-level engineer can read it in a day; the conceptual ramp-up is the real cost. Invalidation semantics — which queries a given write must bust, and which it silently cannot — must be documented and understood by everyone who writes a query. Without that, the cache becomes a correctness liability that surfaces months later as an unexplainable data discrepancy.
Recommendation. Score 0.435 is fair. Do not take this as a production dependency. Mine it for the invalidation pattern, implement a thin owned version or adopt a maintained alternative, and gate rollout on a proven invalidation test matrix with tenant isolation and store-failure degradation both verified.
How can I help you explore Laravel packages today?