yediyuz/laravel-cloudflare-cache
Integrate Cloudflare edge caching into Laravel: cache responses, automatically purge URLs or tags on model changes, and manage cache behavior from familiar Laravel APIs. Reduce origin load and speed up responses with minimal configuration.
Architecture fit. The package occupies the HTTP response layer: a service provider, a middleware that decorates responses with Cache-Control / CDN-Cache-Control / cache-tag headers, a Cloudflare API client for purging, and optional Eloquent observers so model writes trigger tag invalidation. That is a clean seam in Laravel — it does not touch the data layer, the queue, or the ORM, and it composes with existing Cache-Control middleware and Redis-backed app caching rather than replacing them. Best fit is anonymous, read-heavy, GET-only surfaces: marketing pages, catalog/listing pages, public API reads, sitemaps, documentation. Poor fit is anything personalized, session-scoped, or authorization-dependent; the package cannot infer that for you.
Integration feasibility. Mechanically simple: composer require, publish config, set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ZONE_ID, attach the middleware to a route group, verify headers with curl -I and cf-cache-status. Estimated 1–3 engineer-days for a staging pilot including verification. The gating constraint is not code, it is entitlement: tag-based purging is a Cloudflare Enterprise/Cache Tags capability on most plans. If the org is on Pro/Business, the viable pattern collapses to purge-by-URL or purge-everything, which materially changes the invalidation design and the blast radius of a bad purge. Confirm plan tier before committing to an approach.
Technical risk.
Vary, Set-Cookie, and Authorization handling must be explicitly reviewed, not assumed.Key questions for the team.
Stack fit. Laravel-native and idiomatic — service provider, publishable config, facade, middleware, artisan commands. It slots in as an edge layer in front of the existing application cache: Cloudflare at the CDN, Redis for application-level fragments, database behind that. No framework fork, no runtime patching, MIT-licensed. Composer dependency with a small surface area is appropriate for the value delivered.
Migration path. Staged and reversible, with an explicit exit at each gate:
cf-cache-status.Compatibility. Pin the version; verify the Laravel/PHP support matrix against the current release (2025-09-21). Check middleware ordering relative to Laravel's own response middleware and any session/cookie middleware — a misordered middleware is how private responses get cached. Verify behavior under Octane (long-lived workers and static state). Confirm the Cloudflare API token's least-privilege scope and that it is stored in the secrets manager, not .env on a laptop.
Sequencing rationale. Entitlement before code; correctness verification before breadth; invalidation before scale. Do not expand route coverage until Phase 2 is observably working, because breadth without a reliable purge path converts a performance win into a content-integrity problem.
Maintenance. Low code churn expected, but low maintainer redundancy. Budget a few hours per quarter to review releases and pin bumps; keep a vendored-fork contingency (the code surface is small enough that forking is a realistic fallback, which lowers this risk considerably). The real maintenance burden is policy: tag taxonomy and TTLs will drift without an owner.
Support. Community-only — GitHub issues, no vendor SLA, no paid support path. This is acceptable for a performance optimization with a one-line rollback, and unacceptable if it becomes load-bearing for correctness. Name an internal service owner and write the runbook before GA.
Scaling. Scales with Cloudflare's edge rather than your origin, which is the point. The constraint moves to the purge API: rate limits per zone, so prefer tag purges over URL purges, batch and queue invalidations, and debounce model-write storms (bulk imports must not emit one purge per row). Track two numbers: edge hit ratio (the actual KPI) and purge calls per minute against quota.
Failure modes and mitigations.
| Failure | Impact | Detection | Mitigation |
|---|---|---|---|
| Private/auth response cached | Data exposure (Severity 1) | Response-header audit, pen test | Explicit allowlist of cacheable routes; Vary/Set-Cookie review; staging validation |
| Purge API down or token expired | Stale content until TTL | Alert on purge error rate | Short TTLs on volatile routes; alerting on non-2xx purge responses |
| Tag support lost (plan change) | Invalidation silently degrades | Config/plan check in CI | Plan-tier assertion; documented purge-by-URL fallback |
| Over-purge | Origin load spike, cost | Origin latency/5xx dashboard | Tag granularity, queue + debounce |
| Cache poisoning via unkeyed input | Corrupted content to many users | Anomaly review | Strict query-string allowlist; no caching of responses varying on unvalidated input |
| Maintainer abandonment | No upstream fixes | Release cadence review | Vendored fork contingency |
Ramp-up. A Laravel developer familiar with middleware and HTTP caching needs roughly 1–2 days to be productive; the conceptual load is in cache semantics, not the package API. TPM-side effort is mostly coordination: Cloudflare account access and token provisioning through security review, plan-tier confirmation, observability wiring, and defining the acceptable-staleness policy per route with product owners.
Overall recommendation. Treat this as a guarded pilot, not a strategic bet. The score profile (2.215 overall, 1.14 opportunity) is consistent with a narrow, competent utility in a crowded space. It is worth adopting where (a) the Cloudflare plan already supports tags, (b) routes are unambiguously public, and (c) an owner exists for the invalidation contract. If any of those three is false, the cost of getting it wrong — a data-exposure incident or a stale-content incident — exceeds the performance gain, and the effort is better spent on cache rules and Redis tuning inside the application.
How can I help you explore Laravel packages today?