OPcache

On this page 7

OPcache is the PHP extension that stores precompiled script bytecode in shared memory, so that PHP does not have to read, parse and compile the same source files on every request. In server performance, it is one of the most effective single settings for PHP applications: it reduces CPU time per request, lowers latency and increases the throughput a PHP worker pool can sustain.

OPcache has been bundled with PHP since version 5.5 and is the standard opcode cache for PHP-FPM, Apache mod_php and command-line workers. It does not cache application data or HTML output; it caches compiled code, which is a different layer from object caches and page caches.

How OPcache removes repeated compilation

Without an opcode cache, PHP runs a full compile pipeline on every request: it reads each included file, tokenizes it, builds an abstract syntax tree and compiles it into opcodes, the instructions executed by the Zend Engine. For a framework that loads hundreds of files, that pipeline can consume a large share of request time.

OPcache intercepts compilation. The first request compiles a file and stores the resulting opcodes, together with interned strings and class metadata, in a shared memory segment used by all worker processes of the same pool. Later requests execute the cached opcodes directly, and the extension also applies optimizer passes such as constant folding and dead-code removal.

StepWithout OPcacheWith OPcache (warm cache)
Read source filesEvery requestOnly when revalidation detects a change
Tokenize and parseEvery requestSkipped
Compile to opcodesEvery requestSkipped
Optimize opcodesNot performedOnce, at cache time
Execute opcodesEvery requestEvery request
Request processing with and without OPcache

Key OPcache settings and their ranges

OPcache is configured through php.ini directives, and default values are often too small for large applications. The most important settings control memory size, the number of cached files and how the cache notices code changes.

DirectiveCommon valuesWhat it controls
opcache.memory_consumption128-512 MBSize of the shared memory segment in megabytes
opcache.interned_strings_buffer8-64 MBMemory for deduplicated strings
opcache.max_accelerated_files10000-100000Maximum number of cached scripts
opcache.validate_timestamps1 in development, 0 in productionWhether file changes are checked
opcache.revalidate_freq0-60 secondsHow often timestamps are checked when enabled
opcache.jit_buffer_size0 or 64-256 MBMemory for the JIT in PHP 8 and later
Main OPcache directives

With timestamp validation disabled, PHP never checks whether files changed, which saves file system calls but means a deployment must reset the cache explicitly, usually by reloading PHP-FPM. Teams that deploy by switching a symlink should also consider realpath cache behavior, because stale resolved paths can keep old code in use.

OPcache compared with other PHP caching layers

OPcache is often confused with other caches in a PHP stack. Each layer removes a different kind of repeated work, and a well-tuned server typically uses several of them together.

LayerWhat is cachedScope
OPcacheCompiled bytecode of PHP filesShared memory per PHP pool
OPcache preloadingClasses and functions loaded at startupWhole pool, PHP 7.4 and later
JIT compilerMachine code for hot opcode pathsPart of OPcache in PHP 8 and later
Object cacheQuery results and computed dataRedis, Memcached or APCu
Page cacheComplete HTML responsesReverse proxy, CDN or plugin
Caching layers in a PHP application

The JIT benefits CPU-heavy computation such as image processing or mathematics, but typical database-bound web applications see modest gains from it, because their time is spent waiting on I/O rather than executing PHP instructions. Opcode caching itself, by contrast, helps almost every PHP workload.

Monitoring OPcache on a production server

OPcache exposes its state through opcache_get_status(), which reports memory usage, hit rate, cached script count and restart counters. A healthy production cache shows a hit rate close to 100 percent after warm-up and no out-of-memory restarts.

SymptomLikely causeFix
Frequent cache restartsMemory segment fullRaise memory_consumption
Scripts not cachedmax_accelerated_files too lowRaise it above the project file count
Old code after deploymentValidation disabled and no resetReload PHP-FPM as a deploy step
Interned strings buffer fullLarge frameworks with many stringsRaise interned_strings_buffer
High wasted memoryMany invalidated scriptsSchedule a controlled reset during deployment
OPcache symptoms and fixes

Because the cache lives in each pool’s memory, the command-line interface has its own setting, opcache.enable_cli, which is usually off. Cron jobs therefore do not benefit from the web cache, and resetting OPcache from a CLI script does not clear the PHP-FPM cache.

Limitations and security considerations

  • Shared pools on multi-tenant hosts: when several sites share one pool, cached code and status functions can leak information between them, so separate pools per site are advisable.
  • Memory fragmentation: invalidated scripts are not freed immediately; wasted memory accumulates until a restart.
  • Cold starts: after a reload, the first requests compile everything again and show higher latency, which matters on high-traffic servers.
  • Not a fix for slow queries: OPcache removes compile time only; database and network latency remain unchanged.

Put simply

PHP code is written in a form people can read, and the server has to translate it before running it. Without OPcache, the server translates the same pages again for every visitor, like a chef rereading and reinterpreting a recipe for every plate.

OPcache keeps the translated version in memory. The translation happens once, and every later visitor gets the ready version, so the server does less work and answers faster.

In practice

A company runs a large PHP content platform on four application servers with PHP-FPM. Profiling shows that a significant part of each request is spent compiling about 3,000 framework files, and the status report reveals repeated cache restarts because the default memory segment is full.

The team raises opcache.memory_consumption to 256 MB, sets opcache.max_accelerated_files to 20000, disables timestamp validation and adds a PHP-FPM reload to the deployment script. Cache restarts stop, CPU usage per request drops noticeably, and the same servers handle traffic peaks that previously required adding a fifth node.