Zend OPcache: werking, installatie en instellingen, met de php.ini-waarden en het uitschakelen van JIT
Zend OPcache is een PHP-extensie die PHP-scripts naar bytecode compileert en in gedeeld geheugen opslaat, zodat het compileren wordt overgeslagen als hetzelfde bestand opnieuw wordt uitgevoerd. Toen het inschakelen van JIT op een WordPress-server met PHP 8.3 op alle pagina's een 500-fout veroorzaakte, werd de server hersteld door OPcache te laten staan en alleen JIT uit te schakelen.
Sinds PHP 5.5 wordt OPcache standaard met PHP meegeleverd.
1️⃣ Concept van Zend OPcache: bytecode cachen
Bij elk verzoek doorloopt een PHP-script drie stappen: het bestand lezen, naar bytecode compileren en uitvoeren. Als OPcache actief is, vallen vanaf het tweede verzoek voor hetzelfde bestand de eerste twee stappen weg en blijft alleen het uitvoeren over.
Het gedeelde geheugen waarin OPcache de bytecode opslaat, wordt door alle workers van PHP-FPM samen gebruikt. Als meerdere sites op dezelfde PHP-FPM zijn aangesloten, worden ook de scripts van die sites in één gedeeld geheugen opgeslagen.
OPcache slaat gecompileerde PHP-code op, dus PHP-uitvoering en databasequery's gebeuren nog steeds bij elke paginaweergave. Het uitvoeren van PHP helemaal overslaan door kant-en-klare HTML op te slaan is de taak van een paginacache.
2️⃣ De installatie van PHP OPcache controleren
Of OPcache is geïnstalleerd, zie je in de laatste regel van de uitvoer van [php -v].
php -vPHP 8.3.22 (cli) (built: Jun 3 2025 17:17:57) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.3.22, Copyright (c) Zend Technologies
with Zend OPcache v8.3.22, Copyright (c), by Zend TechnologiesOntbreekt de laatste regel, installeer het dan met dnf. De pakketnaam is meestal php-opcache; als je meerdere PHP-versies naast elkaar uit de Remi-repository hebt geïnstalleerd, komt er een versie bij, zoals in php83-php-opcache.
dnf -y install php-opcacheHet pakket php-opcache uit de Remi-repository laadt de extensie via de regel [zend_extension=opcache] in [/etc/php.d/10-opcache.ini]. Herstart PHP-FPM na het installeren, zodat OPcache ook voor webverzoeken geldt.
3️⃣ OPcache-instellingen: php.ini-waarden
OPcache-instellingen kunnen op twee plekken staan: in het deel [opcache] van [/etc/php.ini] en in [/etc/php.d/10-opcache.ini].
php --iniConfiguration File (php.ini) Path: /etc
Loaded Configuration File: /etc/php.ini
Scan for additional .ini files in: /etc/php.d
Additional .ini files parsed: /etc/php.d/10-opcache.ini,Bestanden in de map php.d worden na php.ini gelezen. Staat dezelfde instelling op beide plekken, dan geldt dus de waarde uit php.d.
De tabel hieronder toont de standaardwaarden van PHP 8.3 en de waarden die op de gecontroleerde WordPress-server zijn toegepast.
| Onderdeel | Standaardwaarde in PHP 8.3 | Toegepaste waarde | Betekenis |
|---|---|---|---|
| opcache.enable | 1 | 1 | OPcache gebruiken |
| opcache.enable_cli | 0 | 1 | Ook gebruikt door PHP op de opdrachtregel (wp-cli enzovoort) |
| opcache.memory_consumption | 128 | 1024 | Gedeeld geheugen waarin de bytecode wordt opgeslagen (MB) |
| opcache.interned_strings_buffer | 8 | 16 | Geheugen dat dezelfde tekenreeks maar één keer opslaat (MB) |
| opcache.max_accelerated_files | 10000 | 10000 | Bovengrens voor het aantal sleutels dat gecachet kan worden (de werkelijke grens is een priemgetal vanaf deze waarde: 16229 bij 10000) |
| opcache.max_wasted_percentage | 5 | 10 | Als het geheugen opraakt en de verspilde ruimte dit percentage overschrijdt, wordt de cache geleegd en opnieuw gestart |
| opcache.validate_timestamps | 1 | 1 | Controleert of bestanden zijn gewijzigd |
| opcache.revalidate_freq | 2 | 60 | Hoe vaak op bestandswijzigingen wordt gecontroleerd (seconden) |
| opcache.jit | tracing | disable | JIT-modus (vanaf PHP 8.4 is de standaardwaarde disable) |
| opcache.jit_buffer_size | 0 | 0 | JIT-geheugen; bij 0 werkt JIT niet (vanaf PHP 8.4 is de standaardwaarde 64M) |
De waarden in het deel [opcache] van [/etc/php.ini] staan hieronder. De geheugengrootte stem je af op het servergeheugen en [opcache.max_accelerated_files] op het aantal WordPress-bestanden.
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=1024
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.max_wasted_percentage=10
opcache.validate_timestamps=1
opcache.revalidate_freq=60Als je opnieuw een regel [zend_extension] in php.ini zet, wordt de extensie twee keer geladen en verschijnt de waarschuwing [Cannot load Zend OPcache].
Bij [opcache.revalidate_freq] op 60 kan na het aanpassen van een PHP-bestand nog maximaal 60 seconden de oude code draaien.
Laat [opcache.validate_timestamps] op een WordPress-server waar PHP-bestanden vaak veranderen op 1 staan, zodat bestandswijzigingen worden gecontroleerd. De 0 die de Symfony-documentatie voor productieservers aanraadt, past bij servers waar PHP-bestanden alleen veranderen als een nieuwe versie wordt uitgerold.
Ook met [opcache.validate_timestamps] op 0 leegt WordPress zelf de cache van gewijzigde bestanden als je vanuit het beheerscherm bijwerkt. Werk je echter bij met wp-cli of pas je bestanden aan via SSH, dan blijft de oude code draaien tot PHP-FPM wordt herstart.
4️⃣ JIT van OPcache uitschakelen
De JIT van PHP 8 versnelt werk dat veel van de processor vraagt, dus het effect is klein bij een toepassing als WordPress, die webverzoeken afhandelt. Ook in de WordPress-meting in de PHP JIT RFC haalde de run met JIT 326 verzoeken per seconde en de run zonder JIT 315.
Op een WordPress-server met PHP 8.3.22 werd JIT ingeschakeld met [opcache.jit=tracing] en [opcache.jit_buffer_size=128M]. Drie dagen later, op een dag waarop een stortvloed aan verzoeken de workers van PHP-FPM meerdere keren liet herstarten, trad op alle pagina's een 500-fout op.
In het foutlogboek stond de melding [Allowed memory size of 1073741824 bytes exhausted]. De [tried to allocate 4295229440 bytes] die erop volgt, registreert een poging om in één keer 4 GB toe te wijzen bij een PHP-geheugenlimiet van 1 GB. Nadat JIT was uitgeschakeld, werden dezelfde verzoeken normaal afgehandeld.
JIT schakel je uit door de twee onderstaande regels in [/etc/php.d/10-opcache.ini] te zetten. Ook als er in [/etc/php.ini] nog JIT-instellingen staan, gelden de waarden uit dit bestand.
opcache.jit=disable
opcache.jit_buffer_size=0In PHP 8.3 is de standaardwaarde van [opcache.jit_buffer_size] 0, dus JIT werkt niet als je het niet apart instelt. Vanaf PHP 8.4 is ook de standaardwaarde van [opcache.jit] disable.
5️⃣ De instellingen toepassen en controleren
Gewijzigde instellingen gelden pas nadat PHP-FPM is herstart.
systemctl restart php-fpmNa het herstarten wordt het gedeelde geheugen van OPcache geleegd en met de nieuwe instellingen opnieuw toegewezen.
php -i | grep -E '^opcache\.(enable|memory_consumption|revalidate_freq|validate_timestamps|jit) 'opcache.enable => On => On
opcache.jit => disable => disable
opcache.memory_consumption => 1024 => 1024
opcache.revalidate_freq => 60 => 60
opcache.validate_timestamps => On => OnDe waarden die [php -i] toont, zijn de instellingen van PHP op de opdrachtregel. Op RHEL-systemen leest PHP-FPM dezelfde bestanden [/etc/php.ini] en [/etc/php.d], dus de waarden zijn gelijk.
Als je [opcache_get_status()] op de opdrachtregel aanroept, zie je 0 gecachete scripts. PHP op de opdrachtregel maakt bij elke uitvoering nieuw gedeeld geheugen aan, dus het gebruik van PHP-FPM controleer je door het onderstaande bestand in de webdocumentmap te zetten en in de browser te openen.
<?php
header('Content-Type: text/plain');
$s = opcache_get_status(false);
print_r($s['memory_usage']);
print_r($s['opcache_statistics']);
print_r($s['interned_strings_usage']);
var_dump($s['cache_full']);Als [cache_full] true is, is het gedeelde geheugen of zijn de sleutels vol. Verwijder dit bestand direct na de controle.
Op een server waar drie WordPress-sites dezelfde PHP-FPM gebruiken, was 317 MB van de 1024 MB gedeeld geheugen in gebruik. Er waren per site 3.366 tot 4.222 gecachete scripts, in totaal 11.358.
OPcache slaat scripts op onder hun echte pad en maakt voor bestanden die via een relatief pad zijn geladen nog een sleutel aan met de werkmap erbij, waardoor het aantal sleutels groter wordt dan het aantal scripts. Bij 11.358 scripts raakten de sleutels de limiet van 16.229, en ook de stringbuffer van 16 MB had geen vrije ruimte meer.
Als de sleutels vol zijn, worden nieuwe scripts niet gecachet en bij elk verzoek gecompileerd. In 5 minuten en 21 seconden liep het aantal cache-misses op van 18.408 naar 36.027, maar het aantal gecachete scripts bleef 11.358.
Stel op een server met meerdere WordPress-sites of veel plugins [opcache.max_accelerated_files] ruim in, zodat de sleutellimiet niet vol raakt. Bij 20000 is de werkelijke sleutellimiet 32.531. Is de stringbuffer vol, verhoog dan ook [opcache.interned_strings_buffer].
🔢 FAQ & aanbevolen content
Cache
Cache: definitie en alle toepassingsgebieden van caching
Een artikel dat de gebieden indeelt waarin caches worden gebruikt, waaronder OPcache, dat gecompileerde PHP-code opslaat, en de paginacache, die kant-en-klare HTML opslaat.
PHP-FPM
php-fpm max_children-waarschuwing: zoek de oorzaak in de logs voordat je workers bijzet
Een artikel over het vinden van de oorzaak, aan de hand van de logs, van de waarschuwing die verschijnt als alle PHP-FPM-workers die het gedeelde geheugen van OPcache delen bezet zijn.
PHP-FPM
Wat is PHP-FPM | PHP-FPM installeren en instellen
Een artikel over de installatie van PHP-FPM, waarbinnen OPcache draait, de poolinstellingen in www.conf en het herstarten.
ℹ️ Affiliatemelding
De content van deze site bevat affiliatelinks. Koopt een bezoeker via een van deze links een product of dienst, dan ontvangt deze site een commissie van de verkoper. Het bedrag dat de koper betaalt (bij acties gaat het omlaag ↓) wordt daardoor niet hoger. De vermelde prijzen, kortingen en voorraad gelden op het moment van schrijven en kunnen afwijken; controleer ze daarom vóór je aankoop bij de verkoper. Producten worden gekozen en beoordeeld volgens onze eigen criteria, en commissies hebben geen invloed op de volgorde of de inhoud van de beoordelingen.