Managed technical services across Canada
Proudly Canadian

Guide

PHP Performance Tuning for Canadian Web Hosting: OPcache, PHP-FPM, and Memory Settings

PHP configuration has more impact on web application performance than most developers realize. This guide covers OPcache, PHP-FPM pool settings, memory limits, and the specific configuration changes that make the most difference for WordPress and other PHP applications on Canadian VPS hosting.

Editorial process: This article was created with AI assistance and prepared for publication by Gotekky.

Quick answer

What to check first

PHP configuration has more impact on web application performance than most developers realize. This guide covers OPcache, PHP-FPM pool settings, memory limits, and the specific configuration changes that make the most difference for WordPress and other PHP applications on Canadian VPS hosting.

PHP configuration is one of the most impactful and least discussed factors in web application performance. Two servers with identical hardware can deliver very different response times purely because of how PHP is configured. On a Canadian VPS where you control the server environment, the settings below can cut page generation time in half for typical WordPress installations without changing a line of application code.

OPcache: the single biggest PHP performance improvement

PHP is an interpreted language, meaning every request normally requires the server to read the PHP source files, parse them into bytecode, and execute that bytecode. For a WordPress page request that loads the core WordPress files, your theme, and a dozen plugins, this parsing step happens on every single request and is almost entirely wasted work, since the files have not changed. OPcache eliminates this by storing the compiled bytecode in shared memory after the first compilation. Subsequent requests use the cached bytecode directly, skipping the file read and parse entirely.

OPcache is included with PHP 5.5 and later but is not always enabled or correctly sized by default. The configuration that works well for a WordPress site with a moderate plugin set:

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.save_comments=1
opcache.enable_cli=0

The memory_consumption value of 256 MB reserves 256 MB of shared memory for cached bytecode. For a heavily plugged WordPress site, 128 MB fills up and you start seeing OPcache misses. 256 MB is comfortable for sites with 30 to 50 active plugins. The max_accelerated_files setting must be higher than the total number of PHP files in your application. Run find /var/www/yoursite -name "*.php" | wc -l to get the actual count and set max_accelerated_files above it. If the cache cannot hold all your files, files get evicted and must be recompiled on the next request.

PHP-FPM pool configuration for WordPress sites

PHP-FPM (FastCGI Process Manager) handles PHP request processing as a separate service from the web server. The pool configuration determines how many PHP worker processes run simultaneously, how they are managed, and how requests queue when all workers are busy. These settings directly affect how many concurrent users your site can serve without degrading response times.

The two main process management modes are static and dynamic. Static mode starts a fixed number of workers at startup and keeps them running. Dynamic mode adjusts the number of workers based on load. For a production site with consistent traffic, pm = static with a worker count matched to your available memory is more predictable. For a site with highly variable traffic, pm = dynamic with sensible min and max values avoids having idle workers consuming memory during quiet periods.

Calculating the right number of static workers: determine how much memory a single PHP-FPM worker uses under your application. For WordPress, check the output of ps aux --sort=-%mem | grep php-fpm on a server under load. A typical WordPress worker uses 50 to 120 MB. If your VPS has 4 GB of RAM, you should leave at least 1.5 GB for MySQL, the OS, and other processes. That leaves 2.5 GB for PHP workers. At 80 MB per worker, that is 31 workers. Set pm.max_children to 30 as a safe ceiling. Exceeding available memory causes swapping, which degrades performance far more than having fewer workers.

Memory limit, execution time, and upload settings

The memory_limit directive in php.ini sets the maximum memory a single PHP process can allocate. For shared hosting this is often 256 MB. For a VPS where you control the setting, 512 MB is a practical value for most WordPress sites. Higher is not necessarily better: a process using 512 MB means you can run fewer concurrent workers on the same hardware before running out of memory. Set memory_limit high enough that your application never hits it under normal operation, but not so high that one runaway process can consume a significant fraction of available RAM.

max_execution_time controls how long a PHP script can run before being killed. The default of 30 seconds is too short for imports, exports, and some WooCommerce operations. 120 seconds is a reasonable value for most sites. For specific long-running operations like database imports or bulk exports, you can increase this further via the PHP time_limit() function within the script itself rather than raising the global setting. upload_max_filesize and post_max_size need to be large enough for your largest expected file upload. post_max_size must be larger than upload_max_filesize. For a media-heavy site, setting both to 128 MB is a safe practical value.

Redis object caching for WordPress on Canadian VPS

WordPress's default transient and object cache systems store data in the MySQL database. Every cache hit still requires a database query to retrieve the cached value. Redis is an in-memory key-value store that serves cache data orders of magnitude faster than MySQL. Installing Redis on your VPS and connecting WordPress to it via the Redis Object Cache plugin moves all transient and object cache operations to in-memory lookups. For a WooCommerce site, this eliminates a significant fraction of repeated database queries on high-traffic pages like the shop page, category pages, and product pages. Redis uses approximately 50 to 100 MB of RAM for a typical WordPress site's cache footprint, which is a very favourable trade-off against the reduction in MySQL query load.

Gotekky

Need help deciding what to do next?

Tell us what you are seeing and what outcome you need. We will identify whether a managed service, scoped project or paid technical assessment is the right next step.