TubeSum ← Transcribe a video

Everything about OPcache to increase PHP performance (2026)

0h 25m video Published Feb 12, 2026 Transcribed Aug 3, 2026 T Tideways
Intermediate 12 min read For: PHP developers and DevOps engineers looking to optimize application performance through OPcache configuration.
AI Trust Score 75/100
⚠️ Average / Some Fluff

"Delivers a thorough, practical guide to OPcache with actionable settings and advanced tips—solid content that matches the title."

AI Summary

This video provides a comprehensive guide to optimizing PHP performance through OPcache configuration. It covers the three most impactful settings—memory consumption, interned strings buffer, and max accelerated files—along with advanced techniques like preloading, file cache, and JIT, and common pitfalls to avoid.

[00:01]
Why OPcache is essential

PHP compiles scripts to bytecode on every request; OPcache caches this compilation step, saving hundreds of milliseconds per request. Introduced in PHP 5.5, it's now enabled by default in PHP 8.5.

[02:03]
Validating OPcache is working

Check via phpinfo() output (Zend OPcache section) or opcache_get_status() function. The status shows caching is active and provides efficiency statistics.

[03:16]
Three key settings for 95% of gains

opcache.memory_consumption, opcache.interned_strings_buffer, and opcache.max_accelerated_files. Correctly configuring these three delivers up to 95% of possible OPcache performance gains.

[03:43]
Memory consumption tuning

Default is 128MB. For modern frameworks (Symfony, Laravel, etc.), increase to 256MB. Monitor free memory; if it's low or zero, increase the value. Aim for 10-20% free memory at all times.

[06:51]
Interned strings buffer

Interned strings are hard-coded strings (like class names, function names) stored in shared memory. Default is 8MB; increase to 32MB for modern frameworks. It's a share of memory_consumption, so both must be increased together.

[10:31]
Max accelerated files

Defaults to 10,000 files. For large applications, increase to 100,000 or more. Check cached_keys vs max_keys in phpinfo(); if close, increase the limit.

[12:40]
Advanced: validate_timestamps=0

Disabling timestamp validation (opcache.validate_timestamps=0) skips file modification checks, improving performance by 1-3%. Only do this if code never changes at runtime.

[14:26]
Preloading for faster startup

Preloading compiles scripts at PHP-FPM startup, avoiding autoloading and compilation per request. Can save 5-10% for fast scripts. See dedicated video for details.

[15:43]
CLI considerations

OPcache is disabled on CLI by default because each CLI process is separate. For long-running workers, enabling it may help, but watch memory usage.

[16:56]
File cache for cold starts

OPcache can store bytecode on disk (file cache). Useful for serverless (AWS Lambda) to reduce cold starts. PHP 8.5 adds opcache.file_cache_read_only for read-only volumes. Cold starts are rare (0.3% of invocations) and improvement is ~40%.

[21:00]
JIT: not recommended

JIT is part of OPcache but anecdotal evidence shows no clear performance improvement for typical PHP workloads. Test for your specific use case.

[21:57]
Common pitfalls

In Docker (PHP <8.4), OPcache must be explicitly installed. Also, setting OPcache directives via php_admin_value in FPM pool config doesn't work because memory is allocated at startup; use php.ini instead. PHP 8.5 adds a warning for this.

Properly configuring OPcache—especially the three core settings—can dramatically boost PHP performance. Advanced features like preloading and file cache offer additional gains in specific scenarios, but avoid JIT unless you've tested it. Always verify your configuration is actually applied.

Mentioned in this Video

Tutorial Checklist

1 02:03 Verify OPcache is enabled: check phpinfo() for Zend OPcache section or call opcache_get_status().
2 03:43 Set opcache.memory_consumption to 256 (or higher) in php.ini for modern frameworks.
3 06:51 Set opcache.interned_strings_buffer to 32 (or higher) in php.ini, ensuring it's a share of memory_consumption.
4 10:31 Set opcache.max_accelerated_files to 100000 (or higher) in php.ini.
5 12:40 If code never changes at runtime, set opcache.validate_timestamps=0 in php.ini.
6 14:26 Consider implementing OPcache preloading for faster startup (see dedicated video).
7 16:56 For serverless, configure file cache and use opcache.file_cache_read_only (PHP 8.5+) to reduce cold starts.

Study Flashcards (13)

What is the primary purpose of OPcache?

easy Click to reveal answer

To cache the compiled bytecode of PHP scripts, avoiding recompilation on every request.

00:43

What are the three most important OPcache settings?

medium Click to reveal answer

opcache.memory_consumption, opcache.interned_strings_buffer, and opcache.max_accelerated_files.

03:16

What is the default value of opcache.memory_consumption?

easy Click to reveal answer

128 MB.

04:28

What does the interned strings buffer store?

medium Click to reveal answer

Hard-coded strings like class names, function names, and constant names in shared memory.

07:06

What is the recommended value for opcache.interned_strings_buffer for modern frameworks?

easy Click to reveal answer

32 MB.

08:45

What is the default value of opcache.max_accelerated_files?

easy Click to reveal answer

10,000 files.

10:31

What does opcache.validate_timestamps=0 do?

medium Click to reveal answer

It disables checking file modification times, so scripts are never recompiled after initial compilation.

13:12

What is OPcache preloading?

hard Click to reveal answer

Compiling scripts at PHP-FPM startup and loading them into shared memory, so they are available on every request without autoloading.

14:26

Why is OPcache disabled on CLI by default?

medium Click to reveal answer

Because each CLI process is separate, so caching would not be reused across processes, wasting memory.

15:43

What is the file cache in OPcache?

medium Click to reveal answer

A disk-based cache that stores bytecode, useful for reducing cold starts in serverless environments.

16:56

What is the new OPcache setting in PHP 8.5 for read-only file systems?

hard Click to reveal answer

opcache.file_cache_read_only.

19:34

What is the recommended action regarding JIT?

medium Click to reveal answer

Test it for your specific use case; anecdotal evidence shows no clear improvement for typical PHP workloads.

21:00

Why does setting OPcache directives via php_admin_value in FPM pool config not work?

hard Click to reveal answer

Because OPcache memory is allocated at startup, before FPM pool config is read; the setting appears changed but has no effect.

22:59

💡 Key Takeaways

💡

Three settings deliver 95% of gains

Identifies the highest-impact configuration knobs, saving developers time from tuning less effective options.

03:16
📊

Interned strings buffer explained

Clarifies a commonly misunderstood setting and its relationship to memory consumption.

06:51
🔧

validate_timestamps=0 for 1-3% gain

A simple switch that yields measurable performance improvement when code is static.

12:40
🔧

Preloading saves 5-10%

Shows a more advanced optimization for high-performance applications.

14:26
⚖️

Common pitfall: php_admin_value doesn't work

Warns about a subtle configuration mistake that silently disables OPcache tuning.

21:57

[00:01] levers for optimal PHP performance. And let's be honest, you should get this right because it's a basic building block of PHP performance. And it's just a few settings to tune. In this video, I'm going to show you everything you

[00:15] need to know about opcache performance and close with a few hidden gems of opcache changes in PHP 8.5 last year. Even if you have worked with opache for years, there should be something new for you in this video. Mo, I'm Benjamin and

[00:30] in my work, I've focused on PHP performance topics for the last 10 years, helping thousands of developers along the way. Before we start, I would like to ask you to subscribe to this channel if you're interested in

[00:43] everything related to PHP performance. Why do you even need OPC cache? It's simple. PHP compiles every script it runs into an intermediate bite code which is then executed by the virtual machine of PHP. So, it's a two-step

[00:59] approach. The first step, compiling from PHP code to byte code, can be completely cached. And because the step may take several hundreds of milliseconds for every request, it absolutely makes sense to cache it. In PHP 5.5, OPC cache was

[01:17] introduced. So, that's already like a long time ago, about 15 years, it uh was included in PHP core. And before that there were competing extensions. One was called APC and Opcache was a paid product by the Zen company. As none of

[01:33] these extensions were included in the core, the core developers had no way and incentive to make them work during the release. And that usually led to a few months of incompatibilities, crashes, and um you needed to wait a little time

[01:49] to get everything working and before it was stable. with opache in PHP core and was stable. with opache in PHP core and enabled by default in 8.5. This is a thing of the past for a long time now. But how do you validate that opach

[02:03] works? So there are a few default in settings. If the extension is loaded, then it's enabled by default. So you don't have to care about that on the CLI. We will see later there's an additional setting. So if the extension

[02:17] opcache is installed and activated loaded then it should be enabled by default. You can verify this easily through the PHP info output. You will through the PHP info output. You will see a Z opache section. It states that

[02:31] opcache caching is up and running. Um it differentiates between different features. We'll see that later. And it also provides some statistics of its efficiency. There's also a function that you can call op cache get status. It's

[02:47] only available if the extension is actually loaded. So if you call it in a different scenario, the PHP process will crash. But this um script also gives you an output that you can use to evaluate if uh opache is not only loaded but also

[03:02] enabled and configured correctly. You find a way to access the different statistics to see if opcache is running efficiently. But what does running efficiently mean? There's essentially three settings that we look at that

[03:16] control like most of the performance gains around opcache. The first one is opache memory consumption. The second one opache intern strings buffer and the third one is called opcache max accelerated files. If you configure only

[03:30] these three variables correctly, they make up to 95% of the gains that you can make up to 95% of the gains that you can make with opcache possible. The other 5% are through different other changes. Let's start with opcache memory

[03:43] consumption. So this variable defines the size of the shared memory storage used by opcache in megabytes. So as I explained for before opcache caches the step from PHP code to bite code and if you're running uh PHP

[04:01] bite code and if you're running uh PHP um inside Apache mod PHP or PHP FPM or Franken PHP for example you will have many different requests running in many different requests running in parallel and opcache shares this

[04:14] compilation step between all these different workers that are processing different workers that are processing requests. So for one uh process of PHP requests. So for one uh process of PHP there is one op cache. Um so if we

[04:28] declare 128 megabytes which is the default for the opache memory consumption then it will be used for all the PHP scripts that are compiled in this process and all its child processes that are handling workers.

[04:48] not configured correctly? Let's look at the output of um opcache get status. We find a section memory usage. And in the case where it's not

[05:00] efficient, we see that used memory is very high and free memory is very low. If free memory is very low or zero that that means that it's very likely that that means that it's very likely that there um is additional scripts that need

[05:15] to be compiled that need additional memory that couldn't be compiled because memory that couldn't be compiled because of this. And um we can find out with the of this. And um we can find out with the opcache statistics here looking at hits

[05:30] and then specifically at misses meaning um there are scripts being compiled that are not or loaded that are not in are not or loaded that are not in opcache. If this number is higher this

[05:42] means there are some scripts um that are not in opcache. We can see the hit rate not in opcache. We can see the hit rate here 98%. So that's not optimal. It should be like 99.999% or 100% of scripts being cached. You can

[05:57] also see this in tight ways which collects this information across all your servers for an application. Uh where we can see opcache is running low on memory and it suggests a higher value to configure. Um so this is the same

[06:11] information just in a central location across servers for an application running a modern framework like Symfony Laravel or applications built on top Laravel or applications built on top like um Shopware and WordPress and

[06:25] Magento. I really recommend increasing this memory consumption from the default. So the default is 128 to for example 256 for an application that has

[06:37] this configured correctly. you'll see that the free memory always has some breathing room. So there's a few percentage or like even 10 20% of free memory available at all times. The second variable we need to look at is

[06:51] opache intern strings buffer. This is um set to 8 mgabytes default. Um and the first thing that we need to explain is what are intern strings and what is this what are intern strings and what is this buffering. So an intern string in its

[07:06] simplest way is just an hard-coded string in any of your PHP scripts. So let's say you have your own email address configured in a variable to send address configured in a variable to send um an email to. Then this string can be

[07:21] interned because um it's in the PHP script. But also all names of all symbols. So classes, functions, constants, method names, all these are

[07:33] hard-coded strings that can be compiled to an intern string. And an intern string means that opcache stores the value or sort of like the the characters

[07:45] of the string in shared memory and then these shared memory strings are reused across all scripts that are run in parallel. So if you don't have this uh buffer and set it to zero, this means that every request needs to allocate the

[08:01] memory for all these symbol names, all these variable names over and over again. And so it's a lot of wasted uh memory here by reusing the same variables. How can you find out if the intern

[08:16] strings buffer is too low? Again we look at the configuration um uh at the output of opcache get status or the PHP info output also has this if we see intern strings free memory going towards zero or close to

[08:33] memory going towards zero or close to zero here we see also free memory um then this means that there is most likely um an improvement possible by

[08:45] increasing this from 8 megabytes to a higher number and always I always recommend to 32 megabytes especially for modern frameworks. Um and I recently found out that like I thought that 32 was actually megabytes was the highest

[09:00] number you can set this to but you can increase it much further. The only constraint is that the intern string buffer size is a share of the total memory consumption. So if we look at the intern string buffer being 8 mgabytes

[09:17] then um it's a share of the memory consumption. If we increase that to 256 that means eight of those megabytes are for the intern strings and the rest is for the compilation of scripts in general. And uh if we increase this to

[09:34] 32 megabytes it it is essential that you increase the memory consumption from 128 to a higher number. But if you need to increase the intern string buffer to 64,

[09:46] which is sometimes the case for large applications, then you also need to um increase the memory consumption maybe even more. So these two variables um sort of are linked together. Again, you can also find information about this in

[10:00] tideways where it says upcache is running low on intern strings memory and increase this. And if you change that variable and everything is fine then tight will show this to be not a problem

[10:12] anymore. In the output of opcache get status you will also see intern strings usage. You have the buffer size and the amount of memory used and the free memory again here is a number um higher than zero. So you see we have um like

[10:31] 114,000 of strings interned and we still have a lot of free memory available. The third variable we want to look at is opcache max accelerated files. This one defaults to 10,000 files. And here again for

[10:47] modern frameworks like symfony, Laravel, Magento, Shopware, this number is most likely too small. And there's actually no harm to just increasing this to 100,000 and then uh you most likely don't have a problem

[11:03] unless you are using PHP files for caching and you have like a very large vendor directory that is used excessively then maybe you need to increase it even higher. Again you can uh look at the uh PHP info output for

[11:18] upcache uh specifically for cached scripts which um translate to a concept called cached keys internally. So it's in this case almost double the size. Um

[11:31] if the cached keys number here is smaller than the max keys then you're fine. But um if they are close to each other, it makes sense to increase the number of accelerated files to automatically increase the number of

[11:45] cache keys. So these concepts are linked internally in opcache. Um the sort of correlation is a little bit uh tricky and not important to know. Uh it's just important to know cache keys needs to be smaller than max keys. So this gives you

[12:01] smaller than max keys. So this gives you 90 to 95% of the opcache um optimization possibilities if you have set these three variables correctly. That means all the scripts are opache. They are loaded from opcache. The compilation

[12:15] step is never triggered. uh memory is shared between uh the requests with respect to strings and uh reduced memory usage also means uh that uh the scripts

[12:27] are running faster because they don't need to allocate memory and this makes need to allocate memory and this makes uh PHP uh run extremely fast. However, there's also a few hidden gems in opcache where you can squeeze even more

[12:40] performance out of it. And I want to show you some of these and uh explain how they work and if they make sense to you. Let's look at a more advanced opache configuration where we already set the memory consumption to 256 MGB uh

[12:56] accelerated files to 100,000 and increased the intern strings buffer to 32 megabytes. The next thing that you can look at is the uh setting opache validate timestamps. And what this does is whenever a PHP script runs, it checks

[13:12] is whenever a PHP script runs, it checks if the current timestamp of the script, if the current timestamp of the script, the modification timestamp is maybe more recent than the script that is inside opcache itself. And if that's the case,

[13:26] it recompiles us. For this check to be possible, it needs to look at the modification time of a script for every script that is used during a request. And um accessing this information takes a little bit of time. And if you know

[13:43] that your code never changes, so you never deploy over an existing application, you never change code at runtime, then you can just switch this runtime, then you can just switch this to zero and then the code is always

[13:57] loaded from the op cache after compile uh after being compiled once and it will never be reloaded from disk. And this will improve performance by 1 2 3% or

[14:09] something like that depending of the type of application. The second thing that you can look at is opache preloading. Preloading is video and you can find the link in the description. It works like this. Um

[14:26] while opcache compiles a script to bite code um and caches this information, it still needs to go through the autoloading stack and potentially call

[14:38] require once to load a file and then based on this file the classes functions in opcache are copied into the memory. If you uh want to skip this autoloading

[14:52] and compiling step, you can use preloading and preloading compiles the scripts at startup of PHP FPM. uh it puts them into shared memory already all the classes and functions

[15:05] and on every request they are available automatically at the beginning and this saves another few milliseconds depending on if your scripts are running very fast

[15:17] like around 100 milliseconds or less uh you already optimize a lot of performance then you can squeeze another maybe 5% 10% out of your script here if you want to learn the details about opache preloading please look

[15:31] my specific video about this on this channel. Another variable that you can see commonly that we should discuss is opache enable CLI and

[15:43] I want to make a video about this um because it has a lot of information that we need to look at. By default, opcache is not enabled on the CLI uh for different reasons. Specifically, because every chron job, every worker script

[15:59] running on the CLI is its own process. So if it's using and compiling scripts then this will not be reused across a different script and this sort of processing step is wasted and in many

[16:15] cases uh it doesn't make sense to use opcache on the CLI because of that for longunning workers it might make sense because then the script will run

[16:27] faster and because the longunning script just like takes a lot of time um it might make sense to do that. However, this requires additional memory and if you are running a lot of workers or a lot of crunch jobs in parallel, this

[16:42] lot of crunch jobs in parallel, this means you are um closer to the maximum memory of the server um and you need to uh think about this problem and handle this accordingly. The last configuration settings block I want to discuss here is

[16:56] settings block I want to discuss here is related to the file cache that opcache provides. So before we talked about opc cache being um a memory cache that cache being um a memory cache that contains the byte code for every script.

[17:10] contains the byte code for every script. You can also instruct op cache to save this bite code on disk and this is called the file cache. And for some specific um scenarios in the web context this made a lot of sense. You can see

[17:24] here um uh I'm mentioning breath which is a runtime for PHP on um AWS Lambda. is a runtime for PHP on um AWS Lambda. So there's a blog post by Matthew the uh

[17:36] author of Breath about optimizing the cold start time of Laravel on a AWS cold start time of Laravel on a AWS Lambda. What is uh cold start? So if you run a PHP script for the very first time, it needs to be compiled to byte

[17:51] time, it needs to be compiled to byte code and um this code and um this um hurts the first person accessing an application. And if you don't restart PHP FPM a lot of times, then maybe

[18:04] that's fine and you don't need to handle this. But in case of an architecture running on AWS Lambda for example, you have containers that are stopped over a certain amount of time and then they are started when a new user comes in. So the

[18:20] started when a new user comes in. So the likelihood of users running into um cold likelihood of users running into um cold starts. So running against a PHP uh process that has never run the script before is higher and in that case you

[18:33] might want to already warm the cache before. this blog post from Matush um before. this blog post from Matush um explains how he is improving this um and he shows uh let me show you like a little script uh where he uh sort of

[18:48] declares a number of directories he wants to pre-ompile then iterates over all the files and uses a function called opcache compile uses a function called opcache compile file to like compile this script and um

[19:03] file to like compile this script and um if you configure PHP P with the file cache and um using this setting then the opache compile file function will um produce a

[19:19] cache file uh into this cache directory here for every script and then if the memory cache of op cache is empty it will look for the file cache specifically for his example um there are also new variables here one of them

[19:34] are also new variables here one of them is available only in PHP 8.5 which is the file cache read only variable. So this one is new. It allows you to use the file cache on a disk that is read only. So in case where you compile a

[19:50] only. So in case where you compile a container on a right um volume, container on a right um volume, you sort of generate all the file cache um representations of every PHP script that you need and then you write the

[20:05] container to an image. You ship the image to the production system and on the production system the volume is read only. Then you need to set this setting only. Then you need to set this setting which is only available with PHP 8.5.

[20:17] Um, you could even use file cache only, but this doesn't make sense in the web context. It might make sense on the CLI. And with this kind of settings, you can And with this kind of settings, you can um avoid the cold startup time in PHP

[20:31] FPM or Apache. The benefit of this is small. While Matio says that cold starts small. While Matio says that cold starts where 40% faster, he also says that um from his numbers, cold starts are very rare. only about 0.3% of all

[20:46] invocations. So it's not that it happens quite a lot of time and this is a performance improvement that might help you in a specific situation but um a lot of people will not benefit from this

[21:00] additional overhead and all the maintenance getting this set up and running. If we talk about opcache then we should also talk about the JIT because the JIT is part of opcache. However, I don't really feel comfortable

[21:13] um suggesting you to use digit. From anecdotal evidence, it's not clear that anecdotal evidence, it's not clear that it improves PHP scripts at all. Uh both for scripts running in the web context and the CLI contexts. Even for very

[21:27] heavy um processing scripts that only do like a little bit of IO, it seems you like a little bit of IO, it seems you cannot really see a big difference. So um JIT probably needs some additional things to be better. I can't really tell

[21:43] you how. I can't tell you what are the levers for it being efficient or not. It uh needs to be uh addressed for like your use case and you should try it out your use case and you should try it out yourself. So before we close um I think

[21:57] we saw that enabling OPC cache just makes a huge difference and we saw different ways of configuring it. However, one thing that might accidentally happen in your case is that opcache is not even enabled and there's

[22:12] a specific scenario and also specific configuration problems where you seem to think that opcache is available but it's not or it's um the configuration changes you make are not addressed. So, first in Docker with PHP 8.4 before and earlier

[22:29] Docker with PHP 8.4 before and earlier you specifically needed to um install the opcache extension. It was not used by default in the official PHP images. Without this line in your Docker file, Opcache is not even installed and you

[22:44] don't benefit from the performance gains. The second problem that you might have is that you are changing the opcache configuration settings in PHP's opcache configuration settings in PHP's FPM configuration file through the PHP

[22:59] admin value directive. If you do that then if you look at the If you do that then if you look at the PHP info output then you see the changed PHP info output then you see the changed it. So if you see 256 here opcache will

[23:12] it. So if you see 256 here opcache will show this information. However, um show this information. However, um because opcache is such a central extension being loaded, um the memory is actually already allocated at that point

[23:26] and PHP FBM does not have an influence on this setting anymore. So even if we on this setting anymore. So even if we see this here, PHP info shows 256, it still only allocated the default memory of 128.

[23:41] You have to set this inside the PHP in file because only this file is read at file because only this file is read at the startup and then um leads to the allocation of the memory. Uh when PHP FPM comes into play, it comes to a me uh

[23:57] specific pool and reads the pool information that is already too late and um changing it here doesn't take any effect. With PHP 8.5, you will get a warning about this and also it doesn't show the changed value in the PHP info.

[24:12] So, it's easier to find this kind of problem. Before you were kind of at loss, um you would see um the statistics showing um keys not being allocated, memory overrun, but you changed the uh the values again and again and nothing

[24:26] changed. And this um is sort of the problem why this happens. So, I hope you have learned something new. Um, opcache is really a wide topic. Um, it's provides you with like a lot of benefits of PHP performance and there's a few

[24:41] of PHP performance and there's a few things um added in like the last version that allows you to squeeze a little bit more out in special scenarios and there's also like a lot of um certain information that is not very well known

[24:54] about the relationship between memory consumption and intern strings buffer. Um, hopefully you learned something new. If not, please complain in the comments. Uh maybe you can like give me an idea for something more to talk about. I'm

[25:08] always happy hearing from you. If you like this video and want to see more, please subscribe to this channel or subscribe to the newsletter. The link is subscribe to the newsletter. The link is in the description. Bye.

More from Tideways

View all

⚡ Saved you 0h 25m reading this? Transcribe any YouTube video for free — no signup needed.