skip to content

In PHP, what do opcache.validate_timestamps and opcache.revalidate_freq control, and why do production servers often disable validation?

level: middleimportance: must knowfreq 50%

answer

  1. does OPcache notice edited files
  2. validate_timestamps defaults to 1
  3. revalidate_freq defaults to 2 seconds
  4. 0 means never check the disk
  5. then a deploy must reset the cache

basics

~20 s

With opcache.validate_timestamps=1 (the default) OPcache checks a cached script's modification time at most every opcache.revalidate_freq seconds (default 2) and recompiles it if it changed. Production often sets 0: no file checks at all, so a deploy must reset OPcache.

solid answer

~40 s

`opcache.validate_timestamps` decides whether OPcache ever looks at the file on disk again. When it is `1`, the default, OPcache compares the file's modification time with the cached copy, but only if at least `opcache.revalidate_freq` seconds (default `2`) have passed since the last check; `0` means check on every request. Development wants this, so edits show up. Production often sets `validate_timestamps=0`: OPcache then never checks the filesystem, which saves the checks on every included file and means the running code cannot change underneath live requests. The price is that edited files are ignored until the cache is cleared with `opcache_reset()`, `opcache_invalidate()` or a restart of the PHP server process, so the deploy procedure has to do that.

code

ini · 6 lines
ini
; production: never check the disk; the deploy resets OPcache
opcache.validate_timestamps=0

; development: notice edits on every request
; opcache.validate_timestamps=1
; opcache.revalidate_freq=0

go deeper

for a junior

Know that OPcache can check files for changes, that the default checks at most every two seconds, and that production often turns the check off.

for a middle

Explain how validate_timestamps and revalidate_freq interact, what file_update_protection guards against, and why a deploy must clear the cache when validation is off.

for a senior

Tie the setting to the deploy model: immutable releases with validation off and an explicit reset, or in-place edits with validation on and the mixed-code risk that brings.

for a principal

Standardise per-environment OPcache settings across services so a deploy's cache step is part of the pipeline, not tribal knowledge.

## The two directives | Directive | Default | Meaning | |---|---|---| | `opcache.validate_timestamps` | `1` | whether OPcache checks cached scripts against the file on disk | | `opcache.revalidate_freq` | `2` | how many seconds must pass between checks of one script; `0` checks every request | When validation is on, a request that includes a cached script asks: has `revalidate_freq` elapsed since this script was last checked? If so, OPcache compares the file's modification time with the one recorded at compile time. If the file is newer, the cached copy is discarded and the file is compiled again. `revalidate_freq` is ignored entirely when `validate_timestamps` is `0`. ## Why the default suits development On a developer's machine files change constantly. With the defaults, an edit becomes visible within about two seconds, without restarting anything. Setting `revalidate_freq=0` makes it immediate, at the cost of a check on every include. A related directive guards against half-written files: `opcache.file_update_protection` (default `2`) stops OPcache from caching a file modified less than two seconds ago, so a file still being copied is not cached in a truncated state. ## Why production often turns validation off Setting `opcache.validate_timestamps=0` changes three things: 1. **No filesystem checks.** A request in a large application includes hundreds of files. With validation on, some of those requests check modification times; with it off, none do. The saving is small per request but free. 2. **Stable code for the life of the process.** With validation on, a deploy that copies files one by one can leave a request running a mixture of old and new files, compiled as each check happened to fire. With it off, the running code does not change until the cache is explicitly cleared. 3. **An explicit step on every deploy.** Because OPcache never looks at the disk, new code is ignored until the cache is cleared. The manual lists the ways: `opcache_reset()`, `opcache_invalidate()` for individual files, or restarting the server process that owns the cache. The third point is the trade-off. Teams that turn validation off without adding a reset step discover it the first time a deploy "does nothing". ## A caveat in the manual Even with validation off, OPcache may still read a file's timestamp at compile time when `opcache.file_update_protection` or `opcache.max_file_size` is non-zero. That affects when a new file is first cached, not whether a cached file is rechecked. ## Choosing settings per environment - **Development**: keep `validate_timestamps=1`; consider `revalidate_freq=0` for instant feedback. - **Production with immutable builds** (a container image, a fresh release directory per deploy): `validate_timestamps=0`, with the reset or process restart built into the deploy. - **Production where files are edited in place**: validation on, accepting that changes appear within `revalidate_freq` seconds and that a request can briefly see a mix. Whichever you choose, write it in the environment's ini configuration rather than relying on defaults, so reviewers can see the decision. ## Checking the live setting The value that matters is the one the web server's PHP actually runs with, which may differ from what a shell shows, because the CLI and PHP-FPM often read different ini files. Check it from inside the pool: - `opcache_get_configuration()['directives']['opcache.validate_timestamps']` returns the effective value as OPcache sees it. - `ini_get('opcache.validate_timestamps')` returns the string form of the same setting. A small diagnostic script behind an internal-only route is enough. Running `php -i` in a terminal reports the CLI configuration, which is a frequent source of "but it says validation is on" confusion during incident reviews. ## Symptoms of a mismatch - **Validation off, no reset step**: deploys appear to do nothing; restarting PHP-FPM "fixes" it. - **Validation on in production**: after a deploy, a few requests fail with errors about missing methods or classes while old and new files are mixed, then the errors stop by themselves. - **`revalidate_freq` set high with validation on**: changes appear only after a long, unpredictable delay.

  • What does opcache.revalidate_freq=0 do when opcache.validate_timestamps=0?
    Nothing. `revalidate_freq` only sets how often validation runs, and validation is switched off. OPcache never checks modification times, so the frequency has no effect.
  • Why can validation being on still cause trouble during a deploy?
    Files are replaced one at a time, and each cached script is rechecked on its own schedule. For a moment, one request can run a new controller against an old helper file, and a changed signature fails mid-request. Deploying to a fresh directory and switching once avoids the mixture.

saying these in an interview costs you the question

  • revalidate_freq still matters when validate_timestamps is 0
  • With validation off, OPcache picks up changes after two seconds
  • validate_timestamps=0 makes PHP code run noticeably faster by itself
  • The default is validate_timestamps=0
  • Changing a file on disk always invalidates its OPcache entry