# Performance: OPcache, JIT and Profiling — PHP

Source: https://www.skillbyai.com/en/php/p-performance

> Make PHP fast with OPcache, preloading and profiling.

## Where PHP time goes

PHP compiles each script to **opcodes** before running it. **OPcache** caches those opcodes in shared memory so scripts are not recompiled on every request; it is the single most important performance setting and should always be enabled in production, with `opcache.validate_timestamps=0` in immutable deployments (then reset the cache on each deploy). **Preloading** (`opcache.preload`) can load framework classes into memory at server start. The **JIT** compiler (PHP 8.0+) helps CPU-heavy code such as maths and image processing, but typical web applications are dominated by database and network I/O, where it makes little difference. Real performance work starts with **measurement**: profilers such as **Xdebug** (development), **Blackfire**, **Tideways** or **SPX** show which functions and queries consume time. Common wins: fixing N+1 database queries, adding indexes, caching expensive results in Redis or APCu, using `composer dump-autoload --optimize` (classmap) in production, streaming large files, and moving slow work (emails, PDFs, image resizing) to **background queues**. Long-running application servers such as **FrankenPHP**, **RoadRunner** and **Swoole** keep the application booted between requests for further gains, at the cost of handling state carefully.

## Opcode caching

Without OPcache every request recompiles scripts; with it, compiled opcodes are reused from memory.

![Two timelines: the top repeats a compile block before every run block, the bottom compiles once and then shows only run blocks.](assets/figures/php/section-8-map.svg) — Figure 8.1 — Compilation once with OPcache versus every request without it.

## Production OPcache settings

Values are typical starting points; adjust to your codebase size.

```text
; php.ini (production)
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0      ; code never changes in place: reset on deploy
opcache.jit_buffer_size=64M        ; JIT available; most benefit for CPU-heavy code
opcache.jit=tracing

; composer install --no-dev --classmap-authoritative --no-interaction
; after each deploy: reload php-fpm so the opcode cache starts fresh
```

## Measure before optimising

Most slow PHP pages are slow because of database queries or external calls, not PHP itself. A profiler run takes minutes and usually points straight at the real bottleneck.

**Quiz:** What does OPcache do?

- [ ] Caches database query results
- [ ] Compresses HTTP responses
- [x] Caches compiled opcodes in memory so scripts are not recompiled on each request
- [ ] Stores sessions

*Answer:* Caches compiled opcodes in memory so scripts are not recompiled on each request. OPcache avoids repeated compilation, a major performance gain for every PHP application.
