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 Plugin Laravel Package

graham-campbell/cache-plugin

A Laravel package from Graham Campbell that adds a plugin layer to cache stores, letting you attach custom behavior to cache reads, writes, and deletes without changing the underlying driver. Useful for logging, metrics, and other cross-cutting concerns.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is a peripheral-seam package, not a core component. Which seam depends on resolving an identity problem first, and that problem is the single most important thing to settle before any capacity is committed:

  • If it is the HTTPlug/PSR-18 HTTP cache plugin (a PluginClient decorator that persists whole HTTP responses into a PSR-6 pool), it sits at the outbound edge: queue workers calling metered vendors, scheduled syncs pulling reference data, SDK-style clients talking to maps, geocoding, enrichment, KYC, payments-metadata providers. It does not fit request-path rendering, Eloquent, or anything the Http facade is asked to do in a controller. The business framing is spend reduction and integration latency, not page speed.
  • If it is a plugin/extension system for graham-campbell/cache (pluggable stores, configurable TTLs, key namespacing, read/write/forget), it sits inside the application as a cache abstraction layer — Laravel-native, overlapping heavily with what Cache already does, and offering comparatively little marginal value over the base package.

Either way, frame it as enablement infrastructure on the roadmap. It is plumbing, measured in vendor invoices avoided and incidents deflected, and it should never appear on a customer-facing roadmap line.

Integration feasibility. Feasible, but manual in both readings, and the friction is structural rather than incidental:

  • HTTP-cache reading: Laravel's Http facade is Guzzle-native while the plugin decorates a PSR-18 client, so getting it onto the facade path requires a custom client binding, a Guzzle handler-stack equivalent, or — the only option that ages well — an internal typed service that all outbound vendor calls are expected to use. Separately, Laravel's cache repository is not PSR-6, so a pool adapter (symfony/cache or equivalent) must be bound explicitly, carrying its own serialization behavior for PSR-7 bodies and streams.
  • Laravel-cache reading: near drop-in, which sounds better than it is. The value is in graham-campbell/cache, not in this plugin layer; adopting the plugin system means adopting an ecosystem to get defaults and wiring.

Technical risk. Implementation risk is low — the surface is a constructor, a config array, and a handful of key generators; a competent engineer reproduces equivalent behavior in roughly 50–100 lines. Strategic risk is higher and concentrates in three places: the upstream dependency carries most of the real value, so we may be taking a dependency for defaults; zero dependents and a negligible score mean effectively no external validation of this artifact; and it is a single-maintainer package. The defensible posture is "borrow the pattern, own the code" unless a source review surfaces something non-obvious.

Key questions (each maps to a decision or an estimate, not to curiosity):

  • Which product is this actually — a PSR-18 HTTP cache plugin, or a plugin system for graham-campbell/cache? Resolve from composer.json and src/, not from the package blurb. Two of the supplied descriptions disagree; an estimate made before this resolves is provisional.
  • What does it add over its upstream dependency — defaults only, or discovery, pool binding, and config schema? This determines whether adoption saves code or just adds a layer.
  • Does it honor Cache-Control: no-store/private, Vary, and conditional revalidation (ETag/Last-Modified), or is TTL the only lever? This is the difference between correct caching and a mechanism for serving stale user data.
  • What is the cache-key strategy, and is there a documented collision story for tenant-, user-, or locale-scoped responses?
  • Which PSR-6 pool do we bind, where does it live, and how are PSR-7 bodies and streams serialized into it?
  • What PHP/PSR constraints are declared, and does release cadence match our supported PHP matrix?
  • Does swapping the HTTP client silently decouple Http::fake() from existing tests?

Integration Approach

Stack fit. Strongest for standalone PHP services, queue workers, and SDK-style client classes that already speak PSR-18/HTTPlug. Weakest inside Laravel controllers and request paths that go through the Http facade, where we would be working against the framework. The pragmatic posture: adopt for one bounded outbound integration, not as a platform-wide HTTP caching layer, and promote it to a shared external-services building block only after a pilot produces numbers.

Migration path. Assume the status quo is manual Cache::remember() wrapped around HTTP calls, or no caching at all. Replace it inside a single bounded client class: construct the pool → construct the plugin → wrap the client in PluginClient → expose one small typed service that the rest of the codebase calls. Keep the old path behind a config flag for one release so hit rate, latency, and vendor spend can be compared side by side. Because the abstraction boundary is one service, removal is a one-file change — communicate that reversibility upward, since it converts a dependency-adoption decision into a time-boxed experiment.

Compatibility. Verify three things before production code: the package's PHP constraint against our runtime matrix; that the chosen pool adapter serializes PSR-7 responses and streams safely (the usual source of surprise exceptions); and that swapping the client does not decouple the test suite from the real code path. If the codebase leans on Http::fake(), budget a small test-harness rework as an explicit line item — it is easy to miss in estimation and it erodes confidence in unrelated suites.

Sequencing.

  1. Resolution spike (0.5 day). Confirm from source which package this is, what it wraps, what it adds. Output: a one-paragraph verdict plus a LOC comparison against a hand-rolled equivalent.
  2. Wiring spike (1 day). Build the client chain on a throwaway branch, bind a Redis-backed PSR-6 pool, document key namespacing including tenant/user identity.
  3. Policy decision (product + engineering, 1 hour). Agree in writing what is cached, for how long, keyed how, with what body-size cap and what invalidation story. There is no correct answer without this, and it is the deliverable a TPM genuinely owns here.
  4. Pilot (one sprint). One high-volume, read-only, idempotent integration; generous TTLs; a kill switch. Instrument hit rate, p95 latency, and vendor spend before and after.
  5. Promotion gate. Promote to a shared building block, keep it scoped to the pilot, or drop it and own the ~100-line equivalent — decided on pilot data, not on preference.

Operational Impact

Maintenance. Low code churn, but the maintenance burden is relational, not technical: single maintainer, thin release cadence, no downstream users to surface breakage early. Pin the version explicitly, watch upstream for abandonment, and keep the fork-or-reimplement exit warm. Because the abstraction boundary is one service class, exercising that exit is cheap — that is the property to protect in code review.

Support. There is no community to escalate to. Internal ownership is implied by adoption: someone must own the wrapper, the caching policy document, and the on-call runbook entry. Treat "who answers a page at 2 a.m. when the vendor calls start failing or returning stale data" as a staffing question answered before the pilot, not after.

Scaling. The cache pool becomes a shared dependency with its own capacity profile — Redis memory growth, eviction policy, and key cardinality all become production concerns the moment multiple services share a pool. TTL choice is the primary lever on both spend and staleness, and it is a per-integration judgment, not a global default. Critically, the package caches results but does not coalesce concurrent misses, so under load a cold key produces exactly the stampede the cache was meant to prevent; pair it with request coalescing or accept burst behavior deliberately.

Failure modes, ordered by blast radius:

  1. Mis-keyed responses leaking across tenants, users, or locales. Highest severity by a wide margin — this is a data-exposure incident, not a performance regression. Mitigated only by a written key policy and a review gate before anything leaves pilot.
  2. Serving stale data beyond acceptable freshness, particularly if no-store/private or Vary are not honored; correctness risk that surfaces as confusing product bugs.
  3. Silent miss storms — the cache stops hitting (key drift, TTL misconfiguration, pool outage) and the only symptom is a vendor invoice and a rate-limit incident. Without instrumentation this is invisible until finance or an outage notices.
  4. Serialization exceptions on large or binary bodies, appearing as intermittent 500s in jobs.
  5. Unbounded pool growth from wide key cardinality, degrading unrelated tenants of the same Redis instance.
  6. Weakened test coverage if client substitution bypasses Http::fake(), hiding regressions in code paths nobody suspects.

Each of these argues for the same two controls: a kill switch that reverts to direct calls in one config change, and first-party metrics and tracing on hit rate and pool health — observability is not included and must be built.

Ramp-up. The code is learnable in an afternoon; the semantics are not. HTTP caching correctness — freshness, Vary, revalidation, private versus shared caches, key design — is specialist knowledge most engineers have not had to acquire, and it is where the incidents live. Budget for the caching policy document as the real onboarding artifact, plus a short internal walkthrough. Keep the number of people who can change cache keys small and require review on those changes specifically; that single constraint does more for safety than any amount of tooling.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core