• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Installing and Tuning PHP 8.3 OPCache and JIT compiler on Ubuntu 24.04 LTS for CodeIgniter 4 Microservices

Installing and Tuning PHP 8.3 OPCache and JIT compiler on Ubuntu 24.04 LTS for CodeIgniter 4 Microservices

Prerequisites and System Setup

This guide assumes a fresh Ubuntu 24.04 LTS (Noble Numbat) server instance. We will be installing PHP 8.3 from a reputable PPA to ensure the latest stable version. For CodeIgniter 4 microservices, efficient opcode caching and a Just-In-Time (JIT) compiler are crucial for minimizing latency and maximizing throughput. We’ll focus on optimizing OPCache for memory usage and hit rates, and configuring the JIT for optimal performance with typical microservice workloads.

First, update your package list and install essential build tools:

  • Update package list:
  • Install build dependencies:
sudo apt update
sudo apt upgrade -y
sudo apt install -y software-properties-common build-essential autoconf pkg-config libssl-dev libxml2-dev libzip-dev zlib1g-dev

Next, add the Ondřej Surý PPA, which is the de facto standard for up-to-date PHP packages on Debian/Ubuntu systems:

sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

Installing PHP 8.3 with OPCache and JIT

Now, install PHP 8.3 along with the necessary extensions for web development and microservices, including the built-in OPCache. The JIT compiler is enabled by default in PHP 8.3.

sudo apt install php8.3 php8.3-cli php8.3-common php8.3-mysql php8.3-zip php8.3-mbstring php8.3-xml php8.3-curl php8.3-opcache

Verify the installation and check the OPCache and JIT status:

php -v
php -m | grep opcache

The output of php -v should show PHP 8.3.x. The php -m command should list opcache. The JIT compiler is part of the core PHP 8.3 binary and doesn’t require a separate module installation.

Tuning PHP 8.3 OPCache for Microservices

OPCache is critical for microservices as it caches precompiled PHP bytecode in shared memory, eliminating the need to parse and compile PHP scripts on every request. For microservices, which often handle high volumes of small, frequent requests, optimizing OPCache for memory efficiency and high hit rates is paramount.

The primary configuration file for OPCache is located at /etc/php/8.3/cli/conf.d/10-opcache.ini (for CLI) and /etc/php/8.3/fpm/conf.d/10-opcache.ini (for FPM, if you’re using it with a web server like Nginx). We’ll focus on the FPM configuration as it’s more common for microservice deployments behind a load balancer or API gateway.

Edit the FPM OPCache configuration file:

sudo nano /etc/php/8.3/fpm/conf.d/10-opcache.ini

Here are the recommended settings for a microservice environment, along with explanations:

[OPcache]
opcache.enable=1
opcache.enable_cli=0 ; Disable for CLI if not needed, to save memory
opcache.memory_consumption=128 ; MB. Adjust based on your application's code size and traffic. Start with 128MB for typical microservices.
opcache.interned_strings_buffer=16 ; MB. Stores frequently used strings. 16MB is a good starting point.
opcache.max_accelerated_files=10000 ; Number of files to cache. Adjust based on the number of PHP files in your microservices. 10000 is a safe bet for moderate-sized projects.
opcache.revalidate_freq=2 ; Seconds. How often to check for file changes. For production microservices, a higher value (e.g., 60 or even 0 if using zero-downtime deployment) is better to reduce filesystem overhead. Set to 2 for development/testing.
opcache.validate_timestamps=1 ; Set to 0 in production if you have a robust deployment process that guarantees no stale code.
opcache.save_comments=1 ; Keep comments for docblocks if your framework/tools use them. Set to 0 if not needed to save memory.
opcache.enable_file_override=0 ; Crucial for performance. Prevents file_exists() etc. from checking the filesystem if the file is in cache.
opcache.optimization_level=0xFFFFFFFF ; Enable all optimizations.
opcache.jit=tracing ; Enable JIT compiler. Options: off, function, tracing. 'tracing' is generally best for dynamic workloads.
opcache.jit_buffer_size=128M ; JIT buffer size. Adjust based on JIT activity. 128MB is a good starting point.
opcache.error_log=/var/log/php/opcache.log ; Ensure this directory exists and is writable by the web server user (e.g., www-data).
opcache.log_errors=1

Key Tuning Points for Microservices:

  • opcache.memory_consumption: Monitor your application’s memory usage. If OPCache is evicting frequently (check opcache_get_status()), increase this. For many small microservices, 128MB is often sufficient.
  • opcache.revalidate_freq and opcache.validate_timestamps: For production microservices, especially those deployed with zero-downtime strategies (e.g., blue/green deployments, rolling updates), setting opcache.validate_timestamps=0 and opcache.revalidate_freq=0 can significantly reduce I/O and latency. This requires a deployment process that ensures the code on disk is always consistent with what’s expected. If you’re not using such a process, keep validate_timestamps=1 and a reasonable revalidate_freq (e.g., 60 seconds).
  • opcache.enable_file_override=0: This is a significant performance boost. It means PHP will trust the OPCache entirely and bypass filesystem checks for file existence and modification times. This is safe when validate_timestamps is enabled, but even more performant when validate_timestamps=0.
  • opcache.jit=tracing: The tracing JIT compiler analyzes code execution paths and compiles frequently used sections into optimized machine code. This is particularly beneficial for computationally intensive parts of your microservices or for code that is executed very frequently.

After modifying the configuration, restart PHP-FPM (if applicable) and the web server:

sudo systemctl restart php8.3-fpm
sudo systemctl restart nginx # Or your web server

Verifying OPCache and JIT Functionality

To confirm OPCache is working and to monitor its performance, you can use a simple PHP script. Create a file named opcache_status.php in your web server’s document root (or a secure, accessible location).

<?php
// opcache_status.php

if (!function_exists('opcache_get_status')) {
    die('OPcache is not enabled or not available.');
}

$status = opcache_get_status(true); // true to get real-time statistics

if ($status === false) {
    die('Could not retrieve OPcache status.');
}

echo '<h1>OPcache Status</h1>';

echo '<h2>General Status</h2>';
echo '<table border="1">';
echo '<tr><th>OPcache Status</th><td>' . ($status['opcache_enabled'] ? 'Enabled' : 'Disabled') . '</td></tr>';
echo '<tr><th>Cache Full</th><td>' . ($status['cache_full'] ? 'Yes' : 'No') . '</td></tr>';
echo '<tr><th>Memory Usage</th><td>Used: ' . round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . ' MB / Total: ' . round($status['memory_usage']['total_memory'] / 1024 / 1024, 2) . ' MB</td></tr>';
echo '<tr><th>Interned Strings Usage</th><td>Used: ' . round($status['interned_strings_usage']['used_memory'] / 1024 / 1024, 2) . ' MB / Total: ' . round($status['interned_strings_usage']['total_memory'] / 1024 / 1024, 2) . ' MB</td></tr>';
echo '<tr><th>Number of Keys</th><td>' . $status['opcache_statistics']['num_cached_keys'] . '</td></tr>';
echo '<tr><th>Number of Items</th><td>' . $status['opcache_statistics']['num_cached_scripts'] . '</td></tr>';
echo '<tr><th>Number of Wasted Nodes</th><td>' . $status['opcache_statistics']['wasted_memory'] . '</td></tr>';
echo '<tr><th>Start Time</th><td>' . date('Y-m-d H:i:s', $status['opcache_statistics']['start_time']) . '</td></tr>';
echo '<tr><th>Last Reset</th><td>' . ($status['opcache_statistics']['last_restart_time'] ? date('Y-m-d H:i:s', $status['opcache_statistics']['last_restart_time']) : 'Never') . '</td></tr>';
echo '</table>';

echo '<h2>Hit Rate</h2>';
$hits = $status['opcache_statistics']['opcache_hits'];
$misses = $status['opcache_statistics']['opcache_misses'];
$restarts = $status['opcache_statistics'][' மேற்பட்ட_restarts'];
$overall_hits = $hits + $misses;
$hit_rate = $overall_hits > 0 ? ($hits / $overall_hits) * 100 : 0;

echo '<table border="1">';
echo '<tr><th>OPcache Hits</th><td>' . $hits . '</td></tr>';
echo '<tr><th>OPcache Misses</th><td>' . $misses . '</td></tr>';
echo '<tr><th>Cache Full Restarts</th><td>' . $restarts . '</td></tr>';
echo '<tr><th>Hit Rate</th><td>' . number_format($hit_rate, 2) . '%</td></tr>';
echo '</table>';

// JIT Status (PHP 8.3+)
if (isset($status['jit'])) {
    echo '<h2>JIT Status</h2>';
    echo '<table border="1">';
    echo '<tr><th>JIT Enabled</th><td>' . ($status['jit']['enabled'] ? 'Yes' : 'No') . '</td></tr>';
    echo '<tr><th>JIT Buffer Size</th><td>' . $status['jit']['buffer_size'] . ' bytes</td></tr>';
    echo '<tr><th>JIT Max Executions</th><td>' . $status['jit']['max_exits'] . '</td></tr>';
    echo '<tr><th>JIT Opcodes Compiled</th><td>' . $status['jit']['opcodes_compiled'] . '</td></tr>';
    echo '<tr><th>JIT Invocations</th><td>' . $status['jit']['invocations'] . '</td></tr>';
    echo '</table>';
} else {
    echo '<p>JIT information not available (requires PHP 8.3+ and specific configuration).</p>';
}

?>

Access this script via your browser (e.g., http://your_server_ip/opcache_status.php). A high hit rate (ideally > 99%) is crucial. If the hit rate is low, it indicates that scripts are being recompiled frequently, suggesting insufficient memory, too frequent validation, or an issue with the cache. Monitor the JIT statistics to ensure it’s actively compiling opcodes.

Integrating with CodeIgniter 4 Microservices

CodeIgniter 4 is designed with performance in mind, and with OPCache and JIT enabled and tuned, it will leverage these PHP optimizations automatically. There’s no specific CodeIgniter configuration required to “enable” OPCache or JIT; they operate at the PHP interpreter level.

However, for microservices, consider the following:

  • Autoloader Optimization: CodeIgniter 4’s PSR-4 autoloader is already quite efficient. Ensure your microservices are structured to minimize the number of files loaded per request.
  • Dependency Injection: Use dependency injection to manage services and reduce redundant object instantiation.
  • Caching Layers: While OPCache caches compiled PHP code, you’ll still need application-level caching (e.g., Redis, Memcached) for database query results, API responses, or computed data.
  • Configuration Management: For microservices, consider externalizing configuration (e.g., environment variables, dedicated config services) rather than relying solely on PHP files that might be cached by OPCache. If your configuration changes frequently, ensure your deployment process handles cache invalidation or restarts appropriately if validate_timestamps is off.

Advanced JIT Tuning and Considerations

While opcache.jit=tracing is a strong default, you might explore other JIT modes or fine-tune its parameters based on profiling your specific microservice workloads.

JIT Modes:

  • off: Disables JIT.
  • function: Compiles functions when they are called for the first time. Less aggressive than tracing.
  • tracing: Compiles frequently executed code paths (traces) based on runtime analysis. Generally offers the best performance for dynamic workloads but can have higher overhead.

JIT Tuning Parameters:

  • opcache.jit_buffer_size: The size of the buffer for JIT-compiled code. If you see many JIT invocations but few opcodes compiled, or if your JIT buffer is constantly full, you might need to increase this.
  • opcache.jit_hot_loop_count: (PHP 8.3+) The number of times a loop must be entered for it to be considered “hot” and eligible for JIT compilation. Default is 100.
  • opcache.jit_hot_func_count: (PHP 8.3+) The number of times a function must be called for it to be considered “hot”. Default is 100.
  • opcache.jit_hot_return_count: (PHP 8.3+) The number of times a function must return for its call site to be considered “hot”. Default is 100.

Profiling JIT:

To understand the JIT’s effectiveness, you can use tools like Xdebug with profiling enabled, or specialized PHP profilers. Look for functions or code paths that are frequently executed and are candidates for JIT compilation. The opcache_get_status() output provides basic JIT metrics (opcodes_compiled, invocations) which are a good starting point.

Troubleshooting and Monitoring

Common Issues:

  • OPCache not enabled: Ensure opcache.enable=1 in your php.ini or the specific OPCache config file. Verify the php-opcache module is installed.
  • Low Hit Rate: This is the most common performance bottleneck. Check opcache.memory_consumption, opcache.max_accelerated_files, and opcache.revalidate_freq. If you’re seeing frequent cache clears or high wasted_memory, your memory allocation might be too low, or you have too many files.
  • JIT not working: Ensure opcache.jit is set to function or tracing. Check PHP version compatibility. Some complex code constructs might not be JIT-compatible.
  • Memory Leaks: While OPCache itself is generally stable, poorly written PHP code can still cause memory leaks. Monitor overall server memory usage.
  • Log Files: Regularly check the OPCache log file specified by opcache.error_log for any errors or warnings.

Monitoring Tools:

  • OPCache Status Script: The script provided earlier is essential for real-time monitoring.
  • Server Monitoring Tools: Use tools like Prometheus with Node Exporter, Grafana, or Datadog to monitor CPU, memory, and network I/O. Correlate these with OPCache hit rates and JIT activity.
  • Application Performance Monitoring (APM): Tools like New Relic or Tideways can provide deeper insights into PHP execution times, function calls, and identify bottlenecks that OPCache and JIT can help alleviate.

By carefully configuring and monitoring PHP 8.3’s OPCache and JIT compiler, you can significantly enhance the performance and responsiveness of your CodeIgniter 4 microservices on Ubuntu 24.04 LTS, leading to lower latency and higher throughput.

Reader Interactions

Leave a Reply Cancel reply

You must be logged in to post a comment.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store
  • How to refactor legacy event ticket registers queries using modern WP_Query and custom Transient caching
  • Step-by-Step Guide: Offloading high-frequency member profile directories metadata writes to a Redis KV store

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (662)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • PHP (5)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (647)
  • SEO & Growth (492)
  • Server (118)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (726)
  • WordPress Theme Development (357)

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (726)
  • Debugging & Troubleshooting (662)
  • Security & Compliance (647)
  • SEO & Growth (492)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala