Without OpCache, PHP re-parses and re-compiles every single .php file on every single request — Drupal alone loads hundreds of files per page. OpCache stores the compiled bytecode in shared memory after the first request, so every subsequent request skips parsing entirely. This is the single highest-impact PHP-level setting on any Drupal site, and it's disabled or misconfigured surprisingly often.
What you'll learn in this lesson
- The two settings that matter most: memory allocation and timestamp validation
- Why
validate_timestamps=0is a production-only setting - How to confirm OpCache is actually working, not just enabled
The settings that matter
; php.ini or a dedicated opcache.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=0
memory_consumption (in MB) is the shared-memory pool OpCache stores compiled files in — too small, and it starts evicting cached files under load, silently losing the benefit. max_accelerated_files needs to comfortably exceed your actual file count; Drupal core plus a typical set of contrib modules easily passes 15,000-20,000 PHP files.
The production-only setting
; Production only — NEVER on a development environment.
opcache.validate_timestamps=0
validate_timestamps=0, OpCache stops checking whether a .php file's modification time has changed — meaning it keeps serving the OLD compiled version even after you deploy new code, until the OpCache is explicitly reset (a PHP-FPM reload, typically part of a proper deploy script). On a local dev environment this makes every code change appear to do nothing. Only set it to 0 on production, paired with a deploy process that reloads PHP-FPM after every deploy.Confirming it's actually working
// A quick one-off check via drush or a temporary script:
var_dump(opcache_get_status()['opcache_statistics']);
// Look at 'hits' vs 'misses' — a healthy production site should show
// hits vastly outnumbering misses once warmed up.
Quick check: you deployed new code to production, but the site keeps behaving like the old version. Cache clear didn't help. What's the most likely OpCache-related cause? If you said
validate_timestamps=0is set and PHP-FPM was never reloaded after deploy, you've got the classic version of this exact problem.
Key takeaways
- OpCache eliminates PHP's re-parse-and-compile cost on every request — the single highest-impact PHP setting for Drupal.
- Size
memory_consumptionandmax_accelerated_filesgenerously enough that OpCache never has to evict cached files under normal load. validate_timestamps=0is a real production performance win, but requires a deploy process that reloads PHP-FPM afterward.- Check
opcache_get_status()'s hit/miss ratio to confirm it's actually helping, not just enabled.
Coming up next
OpCache speeds up how fast PHP itself runs. Next, we look at PHP-FPM — the process manager that decides how many of those fast PHP requests can run at once.