vormkracht10/laravel-static
A Laravel package for generating and serving static HTML versions of your routes. Cache pages as flat files to reduce server load, speed up responses, and deploy static content while preserving your existing Laravel routing and Blade views.
Architecture fit. backstagephp/laravel-static sits in the response path as a full-page static cache for Laravel: it writes one file per URI including the query string to a local disk and serves those files directly. That design fits anonymous, highly cacheable, content-driven workloads — marketing sites, docs, blogs, landing pages handed around with campaign links. It does not fit authenticated, personalized, or high-cardinality-query applications, where per-URI file proliferation is guaranteed.
v0.11.0 is an observability release, not a control release. static:status reports storage split by query-string vs. non-query-string URLs, du-style directory rollups with pass-through levels collapsed, top URLs by variant count, most common query parameters, per-host and per-file-type breakdown, age distribution, largest files, and the governing config settings on one screen. --disk=, --limit=, and --json make it scriptable. Notably it is read-only: nothing in this release adds eviction, TTL, or LRU. The only remediation lever named, static:clear --only-with-query-strings, is a blunt instrument.
Integration feasibility. High. Standard Artisan command, no migrations, no new runtime dependency, JSON output for automation. The only new coupling introduced is --json as a de facto monitoring contract.
Technical risk.
static:clear. v0.11.0 makes growth visible; it does not bound it.static:clear --only-with-query-strings cannot distinguish ?utm_source=newsletter from ?page=2, ?sort=price, or ?filter=red. Pruning all query-string variants risks serving stale-or-wrong content or 404s for legitimately distinct pages. This is a correctness risk, not merely a cache-miss cost.--json schema and command semantics may change between minor releases; treat the JSON contract as unstable until 1.0.Key questions for the maintainer.
--json payload versioned, and what is the stability commitment?Vary strategy — are we caching twice?Stack fit. Standard Composer package with Laravel auto-discovery and publishable config; requires a writable local filesystem with inode headroom and web-server rewrite rules (nginx try_files / Apache) to serve the static files. Confirm the supported Laravel/PHP matrix against the composer constraints before committing.
Migration path. Additive if the application currently has no full-page cache, or uses a CDN-only strategy. It is not a drop-in replacement for cache-store-based FPC packages (e.g. response-cache implementations backed by Redis/Memcached): this package writes files, so invalidation cannot be done with Cache::forget(). Teams migrating from a store-backed cache must rebuild their invalidation story around static:clear, which only supports coarse-grained clearing.
Compatibility. Two deployment shapes need explicit handling: (a) multi-node fleets — run static:status per node or against a shared volume using --disk=; the numbers are per-disk, not per-cluster; (b) containerized/ephemeral filesystems — the command will report near-zero and create false confidence that the problem does not exist.
Sequencing.
composer.json; do not float on ^0.11.static:status --json as a baseline.--only-with-query-strings.Maintenance. Pre-1.0 and fast-moving; assume breaking changes in minor versions. Pin, review changelogs on every bump, and keep the upgrade surface small by not building bespoke tooling on the --json schema without a version check.
Support. Community/upstream only; no vendor SLA. The team will need its own runbook for the two predictable incidents: "disk/inode exhaustion" and "status command is slow on the big cache."
Scaling. The diagnostic is explicitly designed for multi-million-file caches, but the underlying design has no eviction. Growth is a direct function of distinct query strings, which bots, newsletter links, and ad platforms generate without bound. Plan for disk exhaustion, inode exhaustion, and degraded directory-listing performance as the realistic ceilings. static:status converts this from a surprise into a known quantity — it does not remove the need for a policy, and a policy needs an owner.
Failure modes.
--json thresholds are wired up without a tuned baseline.Ramp-up. Low for execution — any engineer can run the command and read the summary in minutes. Moderate for interpretation: deciding that "35% of cached pages are URL variants of 11 distinct URLs" is a routing/query-semantics question specific to the application, and choosing between TTL, allow-list, or blunt clear is a judgment call. Budget roughly half a day of a senior engineer to define the policy, plus a short monitoring hookup.
Overall. No prior assessment existed; this establishes the baseline. v0.11.0 is a genuinely useful operational addition that materially improves diagnosability and is worth adopting for that reason alone. It does not address the root cause — unbounded, never-evicted cache growth — and it ships alongside a remediation command with real correctness risk. Recommendation: conditional adoption — take the status/monitoring capability now, defer automated pruning until a TTL or allow-list mechanism exists or the team has explicitly validated which query parameters are safe to discard.
How can I help you explore Laravel packages today?