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

Cache Subscriber Laravel Package

guzzlehttp/cache-subscriber

A Guzzle subscriber that adds caching to HTTP requests, letting you store and reuse responses to reduce redundant network calls. Now deprecated in favor of Guzzle's built-in cache middleware, it remains useful for older projects needing simple response caching.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Recommendation: Do not adopt. This package is archived, deprecated, and architecturally incompatible with the Guzzle version shipped in every supported Laravel release. The pattern it implements is worth reusing; the artifact is not.

Architecture fit guzzlehttp/cache-subscriber is an implementation of RFC 7234 caching as a Guzzle 5 event subscriber — it attaches to $client->getEmitter() and intercepts before/complete/error events to store and replay responses behind a pluggable storage backend. Guzzle 6 removed the event emitter entirely in favor of the middleware/HandlerStack model. Laravel's HTTP layer (Illuminate\Http\Client, which every Http:: call and most first-party integrations use) sits on Guzzle 7. There is no compatibility shim: the package's core abstraction (GuzzleHttp\Event\SubscriberInterface) no longer exists in the dependency graph we would install. This is not a version-pin problem to be solved with a composer.json constraint; it is a dead extension point.

Integration feasibility Low, bordering on nil without forking. To use it we would have to pin guzzlehttp/guzzle to ~5.0 in a Laravel app, which is transitively impossible — laravel/framework requires Guzzle 7, and Guzzle 5 does not support PHP 8. A fork would amount to rewriting the package as a Guzzle 7 middleware, at which point we are not adopting this dependency at all.

Technical risk

  • Abandoned since 2019, archived upstream. No CVE response path, no PHP 8 compatibility work, no maintainer to escalate to. Any security issue in the cache-matching logic is ours to find and fix.
  • Silent correctness failure is the dominant mode. A cache that serves stale or wrong responses does not throw — it returns 200s. For a "private transparent proxy cache," the worst case is cross-user leakage: if the storage backend is shared across requests (filesystem, Redis, APCu), responses to authenticated requests can be replayed to other users unless Vary, Cache-Control: private, and Authorization handling are exactly right. This package predates widespread hardening around that.
  • Zero dependents, 63 stars. No ecosystem signal, no battle-testing, no Stack Overflow surface. We would be the only consumers of a nine-year-old codebase.
  • PHP 8 parse/runtime breakage is likely in Guzzle 5-era code ($str{0} offset syntax, removed each(), implicit nullable params). Even a proof-of-concept would be fighting the runtime.

Key questions

  1. Is there any live service in our estate still pinned to Guzzle 5? If yes, that service is the only possible consumer, and it should be migrated rather than extended.
  2. What is the actual requirement — outbound HTTP response caching to reduce third-party API calls and latency, or RFC-compliant shared-proxy semantics? These have very different solutions.
  3. Does any cached response derive from user-scoped credentials or authorization headers? If so, a shared cache backend is disqualified regardless of library.
  4. Is kevinrob/guzzle-cache-middleware (the maintained Guzzle 6/7 middleware successor to this package) acceptable as a drop-in concept, or does the team prefer a thin in-house middleware over Laravel's Cache contract?
  5. What hit-rate and staleness SLO are we targeting, and how would we observe them?

Integration Approach

Stack fit The concept fits Laravel well; the package does not. Laravel already provides the two pieces we need: a PSR-11-compatible cache store (Cache::store() — Redis, Memcached, database, file) and Guzzle middleware injection via Http::withMiddleware() or a shared HandlerStack bound in a service provider. A caching middleware is roughly 150–250 lines against those primitives, and we control the storage semantics.

Migration path

  1. Confirm the negative. Grep composer.lock across repos for guzzlehttp/guzzle 5.* and for any direct reference to cache-subscriber. Expect zero. Document the finding — this is a cheap gate that closes the ticket.
  2. If a legacy Guzzle 5 consumer exists: treat it as a modernization project, not a caching project. Upgrade to Guzzle 7 first; the caching requirement is re-evaluated afterward.
  3. For the real requirement, evaluate kevinrob/guzzle-cache-middleware as the maintained successor. It is Guzzle 6/7 native, supports PSR-16 storage, and is the de facto migration target for this package's users. Run it behind a spike before committing.
  4. Fallback / preferred: in-house CacheMiddleware registered in AppServiceProvider, keyed on method + URI + relevant Vary headers, storing {status, headers, body, stored_at, ttl} in the Laravel cache store. Explicit, testable, ~1 day of work, no abandoned dependency.

Compatibility Requires Guzzle 7 and PHP 8.1+ (matching the Laravel version in use). The successor middleware is compatible; this package is not. Storage choice must align with the existing cache infrastructure — Redis if already provisioned, otherwise file store for single-node only.

Sequencing

  • Week 1: audit gate + requirement clarification (which outbound integrations, what TTLs, what invalidation triggers).
  • Week 2: spike the successor middleware on one low-risk integration (e.g., a read-only reference-data API). Measure hit rate and p95 latency.
  • Week 3: decide build-vs-adopt; add contract tests for Cache-Control, ETag revalidation, and Authorization bypass.
  • Week 4+: roll out integration by integration behind a config flag, not globally.

Operational Impact

Maintenance Adopting this package means owning it permanently and immediately — there is no upstream to defer to. That is a standing tax on a team that gets no feature velocity in return. The in-house or successor-middleware routes both leave us with code we can read, patch, and test on our own release cadence.

Support None. No maintainer, no issue triage, no security advisories. Any incident debugs from source, on a codebase written for a PHP version we do not run. Compare against a maintained middleware with an active issue tracker, or against our own code with an on-call owner.

Scaling Caching is the scaling lever here, so the mechanism must be sound. File-based storage breaks under multi-node deployment (no shared invalidation, per-node cache divergence). Redis/Memcached storage introduces its own failure mode: a cache outage should degrade to pass-through, not to 5xx. The middleware must be written to fail open, with a circuit breaker or short connect timeout on the store. Also size the store: cached HTTP bodies are unbounded by default and can quietly become the largest keyspace in Redis — enforce a max body size and a hard TTL ceiling.

Failure modes

Mode Symptom Mitigation
Stale data served Callers see outdated records, no error Short TTLs, ETag/Last-Modified revalidation, explicit invalidation hooks
Cross-user leakage User A receives User B's response Bypass cache on Authorization/Cookie; never share a store keyed without identity
Vary mishandling Wrong representation (locale, encoding, API version) Key on all Vary fields; fail closed to no-cache when Vary: *
Cache store outage Latency spike or 5xx Fail-open pass-through, timeouts, health check
Unbounded growth Redis eviction of unrelated keys Max body size, TTL cap, namespaced prefix
Silent regression No errors, gradual data drift Hit-rate/staleness dashboards, sampled cache-vs-origin diffing

Ramp-up Near zero for the pattern, which is well understood. The cost is entirely in the review surface: a new engineer must be able to answer "why did this response come back stale?" without reading a deprecated event-emitter implementation. That argues strongly for code the team wrote, with logging on every cache decision (hit/miss/bypass/revalidate) and a debug header in non-production.

Bottom line: the capability is worth having; this package is not a viable vehicle for it. Close the evaluation as rejected-deprecated, reuse the requirement, and spend the one to three days on the maintained successor or an in-house middleware.

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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels