Skip to main content

OPcache

OPcache is a PHP extension that improves performance by caching precompiled PHP bytecode in shared memory. Instead of parsing and compiling PHP scripts on every request, PHP can reuse cached bytecode, reducing CPU usage and improving response times for PHP applications.

Background and history

PHP historically compiled scripts at runtime for each request, which made CPU consumption and latency scale poorly under traffic. Bytecode caching emerged to reduce this overhead, and OPcache became the widely adopted, built-in bytecode cache included with modern PHP distributions.

OPcache is commonly used on:

  • Web servers running PHP (Apache with PHP-FPM, Nginx with PHP-FPM, OpenLiteSpeed)
  • CMS platforms (WordPress, Drupal, Joomla)
  • PHP frameworks and applications (Laravel, Symfony, custom apps)

Maintained by

  • Maintained by the PHP project community.

Best When to Use

  • Your server runs PHP applications that handle repeated requests (web apps, APIs, CMS).
  • CPU usage is high due to PHP script compilation overhead.
  • You want a low-risk performance improvement without changing application code.
  • You deploy via PHP-FPM or any long-running PHP process model.

Not Suitable When

  • You run short-lived PHP CLI workloads where caching provides little benefit.
  • You cannot allocate shared memory (highly constrained environments).
  • You rely on rapid code changes without controlled reloads (development workflows need different settings).

Compatibility Notes

  • OPcache is typically available by default in modern PHP builds, but may need to be installed or enabled depending on the distribution package.

  • Configuration differs slightly across distros due to file layout (php.ini and conf.d locations).

  • OPcache behavior differs between:

    • PHP-FPM/Apache module (persistent processes benefit most)
    • PHP CLI (optional; often disabled or tuned differently)
  • With containers, OPcache works normally, but ensure the shared memory and configuration are sized for the container limits.

Change safety

Misconfigured OPcache can cause unexpected behavior if application deployment does not trigger PHP-FPM reloads. In production, use a controlled deploy workflow and reload PHP-FPM after code updates.

How OPcache Works

Key points:

  • Cached bytecode lives in shared memory inside the PHP process environment.
  • Cache is shared across worker processes (depends on SAPIs and configuration).
  • Cache invalidation depends on timestamps, revalidation settings, and process reloads.

Installation

Debian/Ubuntu

sudo apt update
sudo apt install php-opcache

RHEL/CentOS Stream/Fedora

sudo dnf install php-opcache

Alpine

sudo apk add php-opcache

Verify OPcache Status (Read-Only)

Check if the extension is loaded

For PHP-FPM or CLI:

php -m | grep -i opcache || true

Show effective configuration

php --ini
php -i | grep -i -E 'opcache|configuration file'

Confirm OPcache is enabled

php -i | grep -i -E '^opcache\.enable|^opcache\.enable_cli'
SAPI differences

php -i reflects the CLI configuration. PHP-FPM and web server SAPIs may use different php.ini and conf.d paths. Always confirm the configuration for the specific SAPI you are running (PHP-FPM pool or Apache module).

Configuration Locations

Common paths (varies by distro and PHP version):

EnvironmentCommon config location examples
--
Debian/Ubuntu (PHP-FPM)/etc/php/<version>/fpm/conf.d/
Debian/Ubuntu (Apache)/etc/php/<version>/apache2/conf.d/
Debian/Ubuntu (CLI)/etc/php/<version>/cli/conf.d/
RHEL/Fedora/etc/php.d/

Use this to find the active paths:

php --ini

Add or adjust OPcache settings in an OPcache ini file (commonly 10-opcache.ini or similar) or in php.ini.

Example baseline (production-oriented):

opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.save_comments=1
opcache.fast_shutdown=1

Meaning of key settings:

SettingPurposeNotes
-
opcache.enableEnable OPcacheShould be 1 for web workloads
opcache.memory_consumptionShared memory size (MB)Increase if cache fills frequently
opcache.max_accelerated_filesScript cache capacitySet based on codebase size
opcache.validate_timestampsDetect file changesKeep 1 unless you always reload on deploy
opcache.revalidate_freqRecheck frequency (seconds)Lower for frequent deploys; higher for stability
opcache.save_commentsKeep doc commentsUsually required for frameworks/annotations
opcache.enable_cliEnable for CLIOften 0 unless needed
Production deployment guideline

If your deployment process reliably reloads PHP-FPM after code changes, you can set opcache.validate_timestamps=0 for better performance. Only do this when you are certain reloads happen every deploy.

Apply Changes Safely

After configuration changes, reload the correct service:

PHP-FPM

Service name depends on PHP version and distro.

sudo systemctl reload php-fpm 2>/dev/null || true
sudo systemctl reload php8.2-fpm 2>/dev/null || true
sudo systemctl reload php8.1-fpm 2>/dev/null || true
sudo systemctl status php-fpm 2>/dev/null || true

If reload is unsupported, restart:

sudo systemctl restart php8.2-fpm 2>/dev/null || true
sudo systemctl restart php-fpm 2>/dev/null || true

Apache with mod_php

sudo systemctl reload apache2 2>/dev/null || sudo systemctl reload httpd 2>/dev/null

Practical Use Cases

Improve WordPress and CMS performance

Baseline:

  • Enable OPcache
  • Ensure enough memory (opcache.memory_consumption)
  • Keep opcache.save_comments=1

Verify improvement:

  • Watch CPU usage under load
  • Confirm fewer compile operations in OPcache stats (if you expose stats internally)

High-traffic PHP API (Laravel/Symfony)

Typical tuning:

  • Increase opcache.max_accelerated_files for larger codebases
  • Ensure opcache.memory_consumption is sufficient
  • Use deploy-triggered reloads to allow safe timestamp validation tuning

Troubleshooting

SymptomLikely CauseSafe ChecksFix
--
OPcache not loadedPackage not installed or extension disabledphp -m, `php -igrep opcache`Install/enable php-opcache, reload PHP-FPM/Apache
No effect on performanceWrong SAPI configuredCompare CLI vs FPM config pathsConfigure OPcache for PHP-FPM/Apache, not only CLI
Frequent cache full / restartsInsufficient memory or file slotsCheck OPcache status, logsIncrease memory_consumption and max_accelerated_files
Users see old code after deployTimestamp checks disabled or low revalidationConfirm deploy reload behaviorReload PHP-FPM on deploy, or enable timestamp validation
Random errors after enableMissing comments or aggressive optimizationsReview settingsEnsure opcache.save_comments=1, revert aggressive flags
Cache invalidation

If you disable timestamp validation and do not reload PHP-FPM on deploy, users may continue running old code indefinitely. Treat deploy-triggered reload as mandatory in that mode.

Security Notes

  • Do not expose OPcache status pages publicly. They can reveal file paths, environment details, and application structure.
  • Use least-privilege access for any diagnostic endpoints, and restrict by network or authentication.

Quick Reference Cheat Sheet

GoalCommand / Setting
---
Check OPcache loadedphp -m | grep -i opcache
Show active ini filesphp --ini
Enable OPcacheopcache.enable=1
Size shared memoryopcache.memory_consumption=128
Keep framework annotationsopcache.save_comments=1
Reload PHP-FPMsudo systemctl reload php8.x-fpm
Reload Apachesudo systemctl reload apache2 or sudo systemctl reload httpd