m6web/cache-extra-bundle
Symfony bundle that integrates m6web/cache-extra, adding tag-based cache invalidation and namespace support on top of PSR-6/Symfony cache pools. Useful when you need to clear groups of entries without flushing the whole backend; wired via bundle DI configuration.
Package identity mismatch — flag first. m6web/cache-extra-bundle is a Symfony bundle (M6Web\Bundle\CacheExtraBundle), not a Laravel package. It integrates via Symfony's DI container, kernel.controller/kernel.response event listeners, and Doctrine annotations. Any evaluation framed as "Laravel/PHP package" needs correcting before a decision is made: in a Laravel codebase it is not installable in any meaningful sense.
Architecture fit. The bundle's value proposition is threefold: (1) declarative per-controller HTTP cache headers (Cache-Control, s-maxage, Vary) via @Cache annotations, (2) a "ban"/purge manager for invalidating entries in a reverse proxy (Varnish/Symfony HttpCache), and (3) ESI "punch hole" helpers for partially cacheable pages. Those concepts are stack-agnostic and genuinely useful; the implementation is bound to Symfony 2.x/3.x idioms that Laravel does not share — no service provider, no middleware pipeline hooks, no config publishing, no facade.
Integration feasibility. Effectively zero for a Laravel target. Concretely blocking:
symfony/http-foundation / symfony/framework-bundle ^2.7|^3.x; a modern Laravel app pulls Symfony 6/7 components. composer require will hard-fail on conflict resolution.Technical risk: high / disqualifying. Zero stars, zero dependents, score 0.03 means no field validation, no downstream triage, and no security response capability. Adopting archived code for caching behavior — where a bug means either stale content served to users or private data cached publicly — is an unacceptable risk profile regardless of code quality.
Key questions for the requesting team:
Recommendation: Reject as a dependency. Harvest the design pattern (it is small — a header-setting listener plus a purge adapter, on the order of a few hundred lines) and reimplement natively.
Stack fit. For a Laravel target, the equivalent surface is:
CachePolicy middleware (or route-middleware with parameters) that sets Cache-Control, s-maxage, stale-while-revalidate, and Vary per route group — this replaces the @Cache annotation.ResponseCache layer if full-response caching is wanted (spatie/laravel-responsecache is maintained and Laravel-native) rather than hand-rolled.CachePurge/CacheBuster service wrapping the CDN's purge API, keyed by surrogate keys or URL tags — this replaces the bundle's ban manager.Migration path. Do not attempt a fork-and-port. Instead:
public vs private, max-age, s-maxage, Vary dimensions, purge key. Sign-off from the team owning auth, because the highest-risk failure is caching a personalized response.purge(array $keys)) with a no-op driver for local/dev and a real driver per CDN.X-Cache-Status/Age headers and cache-hit-ratio metrics from day one; this is the bundle's most reusable idea and the cheapest observability win.Compatibility notes. Modern Symfony already covers most of this natively (#[Cache] attribute, AbstractSessionListener, HttpCache); if a Symfony app is in scope, use that and skip this bundle entirely. Laravel's Cache-Control handling is manual by default, so the middleware is genuinely net-new work, not a port.
Sequencing. (1) Requirement confirmation and proxy-vs-CDN decision — 1 week. (2) Policy taxonomy + threat review — 1 week. (3) Middleware + config — 1–2 weeks. (4) Purge adapter with one CDN — 1–2 weeks. (5) Feature-flagged rollout to a read-only, low-risk route group; expand after a full cache cycle with hit-ratio and staleness review. Total: roughly 4–6 weeks for one engineer, versus a dependency that cannot be installed.
Maintenance. Upstream is archived and read-only; there is no maintenance to inherit and no one to escalate to. Any fork becomes your code permanently. The reimplementation is small enough that ongoing cost is a few days per year (dependency bumps, one CDN SDK upgrade), which is materially cheaper than owning dead third-party code.
Support. No maintainer, no issue triage, no security advisories. A caching bug in this layer manifests as either stale public content or leaked private content — both are incident-grade, and both would land on your on-call with no upstream backstop.
Scaling. Header-setting is stateless and negligible in cost. The purge path is the scaling concern: invalidation fan-out to a CDN is rate-limited and eventually consistent, so the purge service needs batching, retries with backoff, idempotency keys, and a dead-letter path. Design it as async (queued job) rather than inline in the write request, or write latency will degrade under load.
Failure modes to design against:
private, no-store as the default and require explicit opt-in to public, with a test that asserts headers on every authenticated route.Vary mismatch between app and CDN causing cross-user cache collisions.Ramp-up. Low in code volume, moderate in domain knowledge. Engineers need working fluency in HTTP caching semantics (s-maxage, stale-while-revalidate, surrogate keys, Vary) and the specific CDN's purge model — that, not the bundle, is the real onboarding cost. Budget a short internal write-up plus a runbook covering purge failure, cache-hit-ratio regression, and the emergency "disable caching for this route group" switch.
How can I help you explore Laravel packages today?