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

Laravel Opcache Laravel Package

elcobvg/laravel-opcache

A Laravel package for monitoring and managing PHP OPcache. It provides a status dashboard and Artisan commands to clear, reset, and optimize OPcache, helping keep cached PHP scripts fresh after deployments.

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisites

  1. PHP's OPcache extension must be enabled (opcache.enable=1). Confirm with:
    php -r "var_dump(function_exists('opcache_compile_file'), opcache_get_status(false) !== false);"
    
  2. A writable cache directory (the driver stores each cache entry as a compiled PHP file in a directory; OPcache is what makes reading it fast).
  3. A Laravel version the package still supports. This is a small, low-activity package — check the composer.json constraints against your app before installing.

Install and wire it up

composer require elcobvg/laravel-opcache

Laravel 5.5+ package discovery registers Elcobvg\OPcache\OPcacheServiceProvider. On older versions add it to config/app.php. Then register a cache store in config/cache.php:

'opcache' => [
    'driver' => 'opcache',
    'path'   => storage_path('framework/cache/opcache'),
],

Make sure the directory exists and is writable by the web user. If no config is published, check vendor/elcobvg/laravel-opcache/config for the exact keys.

First use case

Use it as a dedicated, read-mostly store — not as your default driver. The classic fit is small, hot data on a single-server app: application settings, feature flags, translation lookups, computed navigation/permissions, third-party API responses.

Cache::store('opcache')->put('settings', $payload, 300);
Cache::store('opcache')->get('settings');

Sanity check it's actually caching in shared memory: opcache_get_status(false)['scripts'] should grow as you read entries.

Implementation Patterns

Keep it as a secondary store. Leave CACHE_DRIVER=file/redis for sessions, queues, and anything that must survive a deploy or a node. Reference the opcache store explicitly:

Cache::store('opcache')->remember('nav.permissions.'.$user->id, 120, fn () => $user->permissions);

Cache-aside for hot reads. The driver's value is in remember/get on the read path. Don't use it for writes-heavy data — every put rewrites a file and calls opcache_invalidate, which is more expensive than a Redis SET.

Warm the cache via HTTP, not artisan. OPcache shared memory is per SAPI pool. Code run in CLI (php artisan, queue workers) uses a completely separate OPcache instance (and usually has OPcache compiled out for CLI). So a deploy-time warming command only helps if opcache.enable_cli=1, and even then it warms the CLI pool, not FPM's. Prime keys from an HTTP endpoint after deploy, or accept lazy population on first hit.

Version/handle your keys across deploys. With OPcache revalidation disabled (see below), an old cached value can outlive your release. Either flush the store on deploy or bake a build hash into keys:

$key = 'v'.config('app.build').'.settings';
Cache::store('opcache')->forget('settings'); // or ->flush() on release

Extend the driver when you need behavior changes (custom serialization, key namespacing, metrics):

Cache::extend('opcache2', fn ($app) => Cache::repository(
    new MyStore($app['config']->get('cache.stores.opcache'))
));

Tags are not supported. If your code calls Cache::tags(...), this driver will throw. Keep tagged caches on Redis/memcached.

Gotchas and Tips

  • OPcache does nothing in CLI by default. opcache.enable_cli=0 means your first test in php artisan tinker will look correct but show no speedup (or behave inconsistently). Test through the web SAPI.
  • The cache is per server. OPcache memory is local to each PHP-FPM pool on each machine. In a multi-node deployment every node has its own copy — great for cache-aside, wrong if you assumed a shared distributed cache (e.g. cache-based locks or rate limiters). Use Redis for those.
  • It shares memory with your application's bytecode. Every cached entry consumes the same opcache.memory_consumption and opcache.max_accelerated_files budget as compiled Laravel/PHP files. A large cache will evict framework scripts from OPcache and slow your whole app down. Keep entries small, tune the limits, and watch opcache_get_status(false) for hits/evictions.
  • Set opcache.validate_timestamps=0 for the speed claim to hold — but then correctness depends entirely on the driver calling opcache_invalidate($path, true) on every write and forget. Verify that in the source. If files are silently revalidated on every include, you're paying a stat per read and the Redis comparison gets much less impressive.
  • opcache.restrict_api and opcache.blacklist_filename can break it. If the cache path falls under a blacklisted pattern, or restrict_api blocks the opcache calls, writes "succeed" but reads fetch stale/empty data. Check opcache_compile_file()'s return value when debugging.
  • TTL doesn't free memory promptly. Expiry is typically checked on read/invalidate; expired entries sit in shared memory until touched. Add a scheduled pruning job or periodically flush if memory pressure matters.
  • Values must be serializable. Closures, resources, and large blobs are poor fits (blobs bloat OPcache). Stick to scalars/arrays/simple DTOs.
  • Concurrent writes to the same key need an atomic temp-file-plus-rename. Review whether the package does this; if not, wrap writes or accept read-while-write risk under load.
  • Debugging checklist: writable + correct path? opcache_get_status()['scripts'] showing the entry files? opcache_invalidate returning true? PHP version compatible with the package's Store interface implementation (Laravel 9/10 changed cache contracts — expect to fork or extend if on a new version)?
  • Maintenance risk. 43 stars and a narrow maintainer surface means new Laravel releases can leave it broken. Pin the version, read the ~few hundred lines of the driver before production, and be prepared to maintain a fork. Benchmark with your payload sizes and hit ratios — the "faster than Redis" claim is a microbenchmark that ignores shared-memory eviction and multi-node reality.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console