PHP 8.3 brings significant performance improvements over previous versions, but default configurations rarely optimize for WordPress workloads. On a VPS where you control the PHP environment, proper tuning can cut page generation time dramatically. This guide covers essential PHP settings for WordPress, from memory allocation to OPcache configuration, with practical values based on typical VPS resources.

📋 Key Takeaways
  • OPcache is the single most impactful PHP optimization for WordPress
  • Memory limits should match your actual usage, not arbitrary high values
  • JIT compilation provides measurable gains for PHP 8.x
  • Monitoring actual resource usage informs better tuning decisions

I. Understanding PHP Performance for WordPress

Before tuning specific settings, understand where PHP spends time when handling WordPress requests.

A. The Request Lifecycle

  • Compilation phase: PHP reads source files and compiles them to opcodes. Without caching, this happens on every request.
  • Execution phase: The PHP engine executes compiled opcodes, running WordPress core, theme, and plugin code.
  • Database interaction: WordPress queries MySQL/MariaDB for content, settings, and user data.
  • Output generation: PHP builds the HTML response by combining templates with database content.

B. Where Tuning Helps

PHP configuration primarily affects compilation and execution phases. Database performance and output caching are separate optimizations.

  • OPcache: Eliminates compilation overhead by caching compiled opcodes between requests.
  • Memory settings: Ensure PHP has sufficient resources without wasting RAM that other services need.
  • JIT compiler: Further optimizes hot code paths by compiling to native machine code.
  • Process management: PHP-FPM settings control how many requests can be handled concurrently.

II. Locating PHP Configuration Files

PHP configuration involves multiple files. Understanding what each controls prevents confusion when making changes.

A. Main Configuration Files

  • php.ini: The main PHP configuration file. Location varies by installation. Use php --ini to find it.
  • PHP-FPM pool config: Found in /etc/php/8.3/fpm/pool.d/www.conf on Debian/Ubuntu. Controls process pool settings.
  • conf.d directory: Additional configuration files in /etc/php/8.3/fpm/conf.d/ that override or extend php.ini.

B. Verifying Current Settings

Before changing settings, verify current values and ensure changes take effect.

  • Command line: Run php -i | grep setting_name to check current values.
  • phpinfo() page: Create a temporary PHP file with <?php phpinfo(); ?> to view all settings in browser.
  • WordPress Site Health: Dashboard > Tools > Site Health shows PHP version and key settings.
  • After changes: Restart PHP-FPM with sudo systemctl restart php8.3-fpm for changes to take effect.

III. Essential php.ini Settings

These settings directly impact WordPress performance and functionality.

A. Memory and Execution Limits

  • memory_limit: Maximum memory a single PHP process can allocate. WordPress recommends 256M minimum. Set to 256M or 512M for most sites.
  • max_execution_time: Maximum seconds a script can run before terminating. Default 30 seconds is usually sufficient. Increase only for specific needs.
  • max_input_time: Maximum time for parsing input data. Default 60 seconds handles most file uploads.
  • max_input_vars: Maximum input variables per request. Increase to 5000 for sites with complex admin pages or many custom fields.

B. File and Upload Settings

  • upload_max_filesize: Maximum size for file uploads. Set to at least 64M for media-heavy publisher sites.
  • post_max_size: Maximum size of POST data. Should be larger than upload_max_filesize. Set to 128M.
  • max_file_uploads: Maximum files uploadable in one request. Default 20 is usually sufficient.
Ad Space - Mid Content

IV. OPcache Configuration

OPcache is the most impactful performance setting for WordPress. It caches compiled PHP code, eliminating compilation overhead on subsequent requests.

A. Core OPcache Settings

  • opcache.enable=1: Enable OPcache. Should already be enabled in PHP 8.3 by default.
  • opcache.memory_consumption=256: Memory in MB for storing cached opcodes. 256MB handles most WordPress sites.
  • opcache.interned_strings_buffer=16: Memory for storing interned strings. 16MB is good for WordPress.
  • opcache.max_accelerated_files=10000: Maximum files to cache. WordPress with plugins may have 5000+ files.
  • opcache.validate_timestamps=0: Disable timestamp checking for production. Files are only recompiled when cache is cleared.
  • opcache.revalidate_freq=0: If timestamps are enabled, how often to check. Set to 0 when validate_timestamps is 0.

B. Production vs Development Settings

  • Production (validate_timestamps=0): Maximum performance but requires manual cache clearing after updates. Clear cache after plugin or theme updates.
  • Development (validate_timestamps=1): Automatically detects file changes but adds overhead checking file modification times.
  • Cache clearing: Clear OPcache by restarting PHP-FPM or using cachetool if installed.

C. Verifying OPcache Effectiveness

  • Check cache usage: Use opcache_get_status() in a PHP script to view cache hit/miss ratios.
  • Target hit rate: A well-configured OPcache should show 95%+ hit rate after warm-up.
  • Memory full warnings: If OPcache runs out of memory, scripts get evicted. Increase memory_consumption.

V. JIT Compiler Configuration

PHP 8.0+ includes a JIT (Just-In-Time) compiler that compiles PHP opcodes to native machine code. For WordPress, gains are modest but measurable.

A. Enabling JIT

  • opcache.jit=1255: Enable JIT with tracing mode optimized for long-running applications. The "1255" value is recommended for WordPress.
  • opcache.jit_buffer_size=128M: Memory allocated for JIT compiled code. 128MB is sufficient for most WordPress sites.

B. JIT Considerations

  • Web workload impact: JIT provides 5-10% improvement for typical WordPress pages. CPU-intensive operations see larger gains.
  • Memory overhead: JIT uses additional memory. Ensure your VPS has RAM to spare.
  • Debugging conflicts: Some debugging tools (Xdebug) are incompatible with JIT. Disable JIT for development if using debuggers.

VI. PHP-FPM Pool Configuration

PHP-FPM manages worker processes that handle requests. Pool configuration determines how many concurrent requests your server can handle.

A. Process Manager Modes

  • pm = dynamic: Recommended for WordPress. Spawns processes as needed within defined limits.
  • pm = static: Keeps a fixed number of processes. Best for consistent high traffic.
  • pm = ondemand: Spawns processes only when needed. Best for low-traffic sites to save memory.

B. Dynamic Pool Settings

  • pm.max_children: Maximum worker processes. Calculate as: (Total RAM - other services) / PHP process size. A 2GB VPS might use 10-20.
  • pm.start_servers: Workers to start initially. Usually 2-4.
  • pm.min_spare_servers: Minimum idle workers to maintain. Usually 2.
  • pm.max_spare_servers: Maximum idle workers before killing extras. Usually equals start_servers.
  • pm.max_requests=500: Requests per worker before respawning. Prevents memory leaks. 500 is good default.

C. Calculating max_children

Each PHP process consumes memory. Setting max_children too high causes swapping; too low limits concurrent handling capacity.

  • Measure actual usage: Check memory per PHP-FPM process with ps aux | grep php-fpm
  • Typical WordPress: 50-100MB per process with typical plugins.
  • Example calculation: 2GB VPS with 1.5GB for PHP: 1500MB / 100MB = 15 max_children

VII. Monitoring and Verification

After tuning, monitoring confirms your changes provide expected improvements.

A. Performance Metrics to Track

  • PHP response time: Time for PHP to generate output before web server adds overhead.
  • OPcache hit rate: Percentage of requests served from opcode cache.
  • Memory usage: Actual memory consumption versus configured limits.
  • FPM process count: Number of active workers during peak traffic.

B. Monitoring Tools

  • PHP-FPM status page: Enable pm.status_path to view pool status via HTTP.
  • Query Monitor plugin: Shows PHP time, queries, and memory for each page load in WordPress.
  • New Relic or similar: Application performance monitoring with detailed PHP profiling.

VIII. Recommended Configuration Summary

For a 2GB VPS running a single WordPress site, these settings provide a good starting point:

  • memory_limit = 256M
  • upload_max_filesize = 64M
  • post_max_size = 128M
  • max_input_vars = 5000
  • opcache.enable = 1
  • opcache.memory_consumption = 256
  • opcache.max_accelerated_files = 10000
  • opcache.validate_timestamps = 0
  • opcache.jit = 1255
  • opcache.jit_buffer_size = 128M
  • pm = dynamic
  • pm.max_children = 15
  • pm.start_servers = 3
  • pm.min_spare_servers = 2
  • pm.max_spare_servers = 4

IX. Conclusion

PHP tuning provides significant WordPress performance gains, especially OPcache configuration. Start with recommended settings, then adjust based on monitoring data from your specific site and traffic patterns. Remember to restart PHP-FPM after configuration changes and clear OPcache after plugin or theme updates when running with validate_timestamps disabled. With proper tuning, PHP 8.3 handles WordPress workloads with impressive efficiency.

What PHP settings made the biggest difference for your WordPress site? Share your tuning tips in the comments!