sixdays/opcache-bundle
Symfony bundle for inspecting and managing PHP OPcache from your app: view cache statistics, memory usage, hit rates, and cached scripts, then reset or invalidate OPcache when needed. Useful for debugging performance and deployments.
Architecture fit — the naming is a trap. Despite being catalogued as a Laravel/PHP package, sixdays/opcache-bundle is a Symfony bundle. It ships a bundle class, DI extension, and a Console command registered through the Symfony kernel. There is no Laravel service provider, no extra.laravel block, no publishable config, no facade. The only thing a Laravel team can reuse is the single command class — the rest is framework wiring we would discard. From a TPM standpoint, the "integration cost" is not installing a package; it is reading and reimplementing one.
The value proposition is a false assurance, not a feature. OPcache shared memory is scoped per-SAPI and per-pool. A CLI invocation has its own segment (or none, with opcache.enable_cli=0) from PHP-FPM. Calling opcache_reset() from a CLI process clears the CLI's cache and leaves the FPM cache — the one serving traffic — untouched. Unless the runtime is unusual (same SAPI, or the tool speaks FastCGI to FPM — this one does not; it is a local function call in a command), the command exits 0 while doing nothing operationally. That is the headline finding. A green deploy step that silently no-ops is worse than no step, because it removes the incident signal.
Technical risk — high on supply chain, low on code volume, high on silent failure. Archived repo, 30 stars, 0 dependents: no upstream fixes, no CVE response, no PHP 8.x / Symfony 6+ compatibility work coming. The command predates execute(): int, so extraction requires modernising the signature and error handling anyway. The dominant failure mode is not a crash — it is a suppressed or misrouted reset behind opcache.restrict_api, disable_functions, or SHM permission errors that return false without surfacing an error.
Key questions before any decision:
opcache.validate_timestamps=0 in production? If not, OPcache revalidates on its own and the whole problem is moot.Stack fit — narrow. Laravel 10/11 on PHP 8.1+. The one point of genuine compatibility is that Laravel commands extend Symfony\Component\Console\Command\Command, so an extracted command class drops in with moderate rewrites. The bundle's DI layer is unusable and should not be bridged.
Migration path — ranked:
| Option | Approach | Verdict |
|---|---|---|
| A | Vendor the ~30-line command into app/Console/Commands/, strip bundle boilerplate, register via Kernel::commands |
Acceptable — same function, zero supply-chain surface, full control over return types and error handling |
| B | Replace with cachetool (maintained, FastCGI-based, actually reaches FPM) wrapped in an artisan command | Recommended if the requirement is real invalidation |
| C | composer require the bundle and bridge Symfony wiring into Laravel |
Reject — no benefit over A; inherits archived-repo risk and stale constraints |
Compatibility. Expect Composer resolution failures against modern Symfony/Laravel constraints. Any extracted code requires execute(): int, typed properties, and #[AsCommand] or an explicit $signature. Critically, verify the reset call's return value (false on failure) and throw rather than log-and-continue — otherwise we ship the silent no-op described above.
Sequencing (do not skip step 1):
composer.json.optimize:clear step, gated to non-local environments.Maintenance. Zero upstream maintenance — archived, no triage, no release cadence. If vendored (Option A), the code becomes ours to own. At ~30 lines that is defensible — roughly an hour of ownership per year — but it must be recorded as a deliberate fork, not an oversight. Budget the decision record, not the code review.
Support. No maintainer, no CVE path. Mitigating factor: MIT license, tiny surface, no network calls, no runtime dependencies beyond Symfony Console. This is precisely why Option A dominates Option C — supply-chain exposure is minimal because we do not install it.
Scaling. Poorly suited to elastic and containerised estates. The command is node-local with no coordination: on a 12-node fleet it must be invoked 12 times, with no partial-failure reporting. In immutable-image deployments OPcache dies with the container on rollout, making the command redundant. Its value is confined to long-lived VMs or FPM pools behind a symlink-based zero-downtime deploy.
Failure modes to design against:
opcache.restrict_api, disable_functions, or SHM/filesystem permission errors returning false.octane:reload (or worker restart) leaves stale code running in worker memory.Ramp-up. Effectively nil for the code — a mid-level engineer understands it in minutes. The real cost is organisational: teaching the team that a CLI OPcache reset does not reach FPM, so the runbook does not encode false safety. That is a 30-minute briefing to the on-call group, and it is the highest-value output of this evaluation regardless of whether we vendor anything.
Recommendation. Do not adopt as a dependency. Adopt the pattern — vendor the ~30 lines as a native artisan command, or, where genuine FPM invalidation is required, replace it with a cachetool-backed command. Treat archived status as disqualifying for composer require and as merely inconvenient for a copy-paste. The deliverable from this evaluation is not code; it is an explicit, verified pipeline requirement ("deploy must invalidate OPcache deterministically, and we can prove it did") plus a runbook entry that no longer relies on an unmaintained bundle to be true.
How can I help you explore Laravel packages today?