Zend OPcache: Konzept, Installation und Konfiguration mit den php.ini-Werten und dem Deaktivieren von JIT

Testumgebung RHEL-FamilieAlmaLinux 9.8root-KontoGeprüft am 2026-10-16

Zend OPcache ist eine PHP-Erweiterung, die PHP-Skripte zu Bytecode kompiliert und im Shared Memory ablegt, sodass das Kompilieren beim nächsten Ausführen derselben Datei entfällt. Als nach dem Aktivieren von JIT auf einem WordPress-Server mit PHP 8.3 auf allen Seiten ein 500-Fehler auftrat, wurde der Server wiederhergestellt, indem OPcache unverändert blieb und nur JIT deaktiviert wurde.

Seit PHP 5.5 wird OPcache standardmäßig mit PHP ausgeliefert.

1️⃣ Konzept von Zend OPcache: Bytecode-Caching

Bei jeder Anfrage durchläuft ein PHP-Skript drei Schritte: Datei lesen, zu Bytecode kompilieren und ausführen. Ist OPcache aktiv, entfallen ab der zweiten Anfrage für dieselbe Datei die ersten beiden Schritte, und es bleibt nur das Ausführen.

Das Shared Memory, in dem OPcache den Bytecode ablegt, wird von allen Workern von PHP-FPM gemeinsam genutzt. Sind mehrere Websites mit demselben PHP-FPM verbunden, liegen auch deren Skripte in einem gemeinsamen Shared Memory.

🧩 Anfragenverarbeitung ohne und mit OPcache
Erklär-Diagramm
🧠 OPcache
📨 Anfrage
🧰 PHP-FPM Worker
Worker 1Erste Anfrage
Worker 2Zweite Anfrage
Worker 3Warten
Drei Schritte bei jeder AnfrageErste Anfrage · drei SchritteNur Ausführen→
⚙️ Verarbeitung des PHP-Skripts
Datei lesenEntfällt
→
Bytecode kompilierenEntfällt
→
AusführenPHP ausführen · Datenbankabfrage
Shared Memory wird nicht genutzt↓ Bytecode speichern↑ Bytecode aus dem Shared Memory verwenden
🧠 Shared Memory
Bytecode (kompilierter PHP-Code)
Von allen Workern von PHP-FPM gemeinsam genutzt · ein einziges Shared Memory, auch bei mehreren Websites
Ohne OPcache durchläuft ein PHP-Skript bei jeder Anfrage drei Schritte: Datei lesen, zu Bytecode kompilieren und ausführen.
Ohne OPcache durchläuft auch die zweite Anfrage für dieselbe Datei wieder alle drei Schritte: Datei lesen, zu Bytecode kompilieren und ausführen.
Ist OPcache aktiv, durchläuft die erste Anfrage die drei Schritte und legt den Bytecode anschließend im Shared Memory ab.
Ab der zweiten Anfrage für dieselbe Datei entfallen die ersten beiden Schritte, und es bleibt nur das Ausführen; das Shared Memory wird von allen Workern von PHP-FPM gemeinsam genutzt.

OPcache speichert kompilierten PHP-Code, deshalb finden PHP-Ausführung und Datenbankabfragen bei jedem Seitenaufruf weiterhin statt. Die PHP-Ausführung ganz zu überspringen, indem fertiges HTML gespeichert wird, ist die Aufgabe eines Seitencaches.

2️⃣ Installation von PHP OPcache prüfen

Ob OPcache installiert ist, siehst du in der letzten Zeile der Ausgabe von [php -v].

php -v
PHP 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 Technologies

Fehlt die letzte Zeile, installiere das Paket mit dnf. Der Paketname lautet meist php-opcache; wurden aus dem Remi-Repository mehrere PHP-Versionen nebeneinander installiert, hängt die Version daran, etwa php83-php-opcache.

dnf -y install php-opcache

Das Paket php-opcache aus dem Remi-Repository lädt die Erweiterung über die Zeile [zend_extension=opcache] in [/etc/php.d/10-opcache.ini]. Starte PHP-FPM nach der Installation neu, damit OPcache auch für Webanfragen gilt.

3️⃣ OPcache-Konfiguration: php.ini-Werte

Die OPcache-Einstellungen können an zwei Stellen stehen: im Abschnitt [opcache] von [/etc/php.ini] und in [/etc/php.d/10-opcache.ini].

php --ini
Configuration 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,

Dateien im Ordner php.d werden nach der php.ini gelesen. Steht derselbe Eintrag an beiden Stellen, gilt daher der Wert aus php.d.

Die folgende Tabelle zeigt die Standardwerte von PHP 8.3 und die Werte, die auf dem geprüften WordPress-Server gelten.

KategorieStandardwert in PHP 8.3Angewendeter WertBedeutung
opcache.enable11OPcache verwenden
opcache.enable_cli01Auch in PHP auf der Kommandozeile verwenden (wp-cli usw.)
opcache.memory_consumption1281024Shared Memory, in dem der Bytecode liegt (MB)
opcache.interned_strings_buffer816Speicher, der gleiche Zeichenketten nur einmal ablegt (MB)
opcache.max_accelerated_files1000010000Obergrenze für die Zahl der cachebaren Schlüssel (die tatsächliche Grenze ist eine Primzahl ab diesem Wert: 16229 bei 10000)
opcache.max_wasted_percentage510Wenn der Speicher knapp wird und der verschwendete Platz diesen Anteil übersteigt, wird der Cache geleert und neu gestartet
opcache.validate_timestamps11Prüfen, ob sich Dateien geändert haben
opcache.revalidate_freq260Wie oft auf Dateiänderungen geprüft wird (Sekunden)
opcache.jittracingdisableJIT-Modus (ab PHP 8.4 ist der Standardwert disable)
opcache.jit_buffer_size00JIT-Speicher; bei 0 läuft JIT nicht (ab PHP 8.4 ist der Standardwert 64M)

Die Werte im Abschnitt [opcache] der [/etc/php.ini] sind unten aufgeführt. Die Speichergröße richtet sich nach dem Arbeitsspeicher des Servers, [opcache.max_accelerated_files] nach der Zahl der WordPress-Dateien.

[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=60

Wird in der php.ini erneut eine Zeile [zend_extension] eingetragen, wird die Erweiterung zweimal geladen, und es erscheint die Warnung [Cannot load Zend OPcache].

Bei [opcache.revalidate_freq] von 60 kann nach dem Ändern einer PHP-Datei noch bis zu 60 Sekunden lang der alte Code laufen.

Auf einem WordPress-Server, auf dem sich PHP-Dateien oft ändern, lässt du [opcache.validate_timestamps] auf 1, damit Dateiänderungen geprüft werden. Die 0, die die Symfony-Dokumentation für Produktivserver empfiehlt, passt zu Servern, auf denen sich PHP-Dateien nur beim Ausrollen einer neuen Version ändern.

Auch bei [opcache.validate_timestamps] auf 0 leert WordPress selbst den Cache der geänderten Dateien, wenn du im Administrationsbereich ein Update machst. Aktualisierst du dagegen mit wp-cli oder änderst Dateien per SSH, läuft der alte Code weiter, bis PHP-FPM neu gestartet wird.

4️⃣ JIT von OPcache deaktivieren

Der JIT-Compiler von PHP 8 beschleunigt rechenintensive Aufgaben, daher bringt er bei einer Anwendung wie WordPress, die Webanfragen bearbeitet, wenig. Auch in der WordPress-Messung im PHP-JIT-RFC schaffte der Lauf mit aktiviertem JIT 326 Anfragen pro Sekunde, der Lauf mit deaktiviertem JIT 315.

Auf einem WordPress-Server mit PHP 8.3.22 wurde JIT mit [opcache.jit=tracing] und [opcache.jit_buffer_size=128M] aktiviert. Drei Tage später, an einem Tag, an dem ein Ansturm von Anfragen die Worker von PHP-FPM mehrmals neu starten ließ, trat auf allen Seiten ein 500-Fehler auf.

Im Fehlerprotokoll stand die Meldung [Allowed memory size of 1073741824 bytes exhausted]. Das darauf folgende [tried to allocate 4295229440 bytes] zeigt den Versuch, bei einem PHP-Speicherlimit von 1 GB auf einmal 4 GB zu reservieren. Nach dem Deaktivieren von JIT wurden dieselben Anfragen normal verarbeitet.

JIT wird deaktiviert, indem die beiden folgenden Zeilen in [/etc/php.d/10-opcache.ini] eingetragen werden. Auch wenn in [/etc/php.ini] noch JIT-Einstellungen stehen, gelten die Werte dieser Datei.

opcache.jit=disable
opcache.jit_buffer_size=0

In PHP 8.3 ist der Standardwert von [opcache.jit_buffer_size] gleich 0, JIT läuft also nicht, solange du es nicht gesondert einstellst. Ab PHP 8.4 ist auch der Standardwert von [opcache.jit] gleich disable.

5️⃣ Konfiguration anwenden und prüfen

Geänderte Einstellungen gelten erst nach einem Neustart von PHP-FPM.

systemctl restart php-fpm

Nach dem Neustart wird das Shared Memory von OPcache geleert und mit den neuen Einstellungen neu zugewiesen.

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 => On

Die von [php -i] ausgegebenen Werte sind die Einstellungen von PHP auf der Kommandozeile. Auf RHEL-Systemen liest PHP-FPM dieselben Dateien [/etc/php.ini] und [/etc/php.d], daher sind die Werte gleich.

Wenn du [opcache_get_status()] auf der Kommandozeile aufrufst, werden 0 gecachte Skripte angezeigt. PHP auf der Kommandozeile legt bei jedem Lauf ein neues Shared Memory an, daher prüfst du die Auslastung von PHP-FPM, indem du die folgende Datei in den Web-Dokumentordner legst und im Browser öffnest.

<?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']);

Ist [cache_full] gleich true, sind das Shared Memory oder die Schlüssel voll. Lösche diese Datei gleich nach der Prüfung.

Auf einem Server, auf dem drei WordPress-Websites dasselbe PHP-FPM nutzen, waren von 1024 MB Shared Memory 317 MB belegt. Es gab pro Website 3.366 bis 4.222 gecachte Skripte, insgesamt 11.358.

OPcache speichert Skripte unter ihrem tatsächlichen Pfad und legt für Dateien, die über einen relativen Pfad geladen werden, einen weiteren Schlüssel mit angehängtem Arbeitsverzeichnis an, deshalb ist die Zahl der Schlüssel größer als die der Skripte. Bei 11.358 Skripten war die Obergrenze von 16.229 Schlüsseln erreicht, und auch der String-Puffer mit 16 MB hatte keinen freien Platz mehr.

Sind die Schlüssel voll, werden neue Skripte nicht gecacht und bei jeder Anfrage kompiliert. Innerhalb von 5 Minuten und 21 Sekunden stiegen die Cache-Misses von 18.408 auf 36.027, die Zahl der gecachten Skripte blieb aber bei 11.358.

Auf einem Server mit mehreren WordPress-Installationen oder vielen Plugins setzt du [opcache.max_accelerated_files] großzügig, damit die Schlüsselgrenze nicht erreicht wird. Bei 20000 liegt die tatsächliche Schlüsselgrenze bei 32.531. Ist der String-Puffer voll, erhöhst du auch [opcache.interned_strings_buffer].

🔢 FAQ & empfohlene Inhalte

Die Einstellung wurde in PHP 7.2 entfernt, daher hat sie in PHP 8 keine Wirkung, auch wenn sie in der php.ini stehen bleibt. Auf einem Server mit übernommenen alten Einstellungen kannst du diese Zeile löschen.

OPcache speichert kompilierten PHP-Code, der Redis-Objekt-Cache speichert Ergebnisse von Datenbankabfragen. Da sie Unterschiedliches speichern, lassen sie sich gemeinsam nutzen.

Auf einem Server, der PHP über PHP-FPM ausführt, arbeitet OPcache innerhalb von PHP-FPM, deshalb wird nur PHP-FPM neu gestartet. Auf einem Server, der PHP als Apache-Modul (mod_php) ausführt, startest du Apache neu.

ℹ️ Affiliate-Hinweis
Die Inhalte dieser Website enthalten Affiliate-Links. Kauft ein Besucher über einen dieser Links ein Produkt oder eine Dienstleistung, erhält die Website vom Verkäufer eine Provision. Der Betrag, den der Käufer zahlt(bei Aktionsrabatten sinkt er ↓), steigt dadurch nicht. Angegebene Preise, Rabatte und Lagerbestände entsprechen dem Stand bei Erstellung und können abweichen; prüfe sie daher vor dem Kauf beim Verkäufer. Produkte werden nach eigenen Kriterien ausgewählt und bewertet, und Provisionen beeinflussen weder die Reihenfolge noch den Inhalt der Bewertungen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Beweisen Sie, dass Sie ein Mensch sind: 8   +   9   =