PHP Optimization

This guide covers the PHP configuration optimizations used in AutoCom for maximum performance in production environments.

Overview

AutoCom uses PHP 8.4 with the following optimizations:

  • OPcache - Bytecode caching for faster execution
  • JIT Compilation - Just-in-time compilation for CPU-intensive operations
  • PHP-FPM - FastCGI Process Manager for handling concurrent requests
  • Realpath Cache - Faster file resolution for autoloading

PHP Configuration (php.ini)

Location

backend/docker/php/php.ini

Error Handling

[PHP]
; Disable error display in production
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
log_errors = On
error_log = /proc/self/fd/2

Resource Limits

; Memory and execution limits
memory_limit = 256M
max_execution_time = 120
max_input_time = 60
post_max_size = 50M
upload_max_filesize = 50M
max_file_uploads = 20
max_input_vars = 5000
Setting Value Purpose
memory_limit 256M Maximum memory per request
max_execution_time 120s Maximum script execution time
post_max_size 50M Maximum POST data size
upload_max_filesize 50M Maximum file upload size

Security Settings

[Security]
expose_php = Off
allow_url_fopen = On
allow_url_include = Off
; Note: proc_open is needed by Laravel for artisan commands
disable_functions = exec,passthru,shell_exec,system,curl_multi_exec,parse_ini_file,show_source

Session Configuration

[Session]
session.use_strict_mode = 1
session.use_cookies = 1
session.use_only_cookies = 1
session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = Strict
session.gc_probability = 0
session.gc_maxlifetime = 1440

Output Optimization

; Output buffering for better performance
output_buffering = 4096
implicit_flush = Off

; Realpath cache - important for autoloading
realpath_cache_size = 4096K
realpath_cache_ttl = 600

; Zlib compression
zlib.output_compression = On
zlib.output_compression_level = 4

OPcache Configuration

OPcache stores precompiled PHP bytecode in memory, eliminating the need to parse and compile scripts on each request.

Basic Settings

[opcache]
opcache.enable = 1
opcache.enable_cli = 1

Memory Settings

; Memory allocation
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 32
opcache.max_accelerated_files = 30000
Setting Value Description
memory_consumption 256MB Shared memory for storing opcode
interned_strings_buffer 32MB Memory for storing interned strings
max_accelerated_files 30000 Maximum cached files (Laravel has ~5000)

Validation Settings

; Production: disable file checks for maximum performance
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0

Important: With validate_timestamps = 0, you must restart PHP-FPM after deploying code changes.

File Cache

; Enable file cache for faster restarts
opcache.file_cache = /tmp/opcache
opcache.file_cache_only = 0
opcache.file_cache_consistency_checks = 0

Optimization Level

; Maximum optimization
opcache.optimization_level = 0x7FFEBFFF
opcache.fast_shutdown = 1
opcache.save_comments = 1  ; Required for Laravel annotations

JIT Compilation

PHP 8.0+ includes a Just-In-Time compiler that translates PHP bytecode to native machine code.

Configuration

[opcache]
; JIT compilation mode
; 1255 = tracing JIT (recommended for web apps)
opcache.jit = 1255
opcache.jit_buffer_size = 128M

JIT Modes

Mode Description Use Case
1255 Tracing JIT Web applications (recommended)
1235 Function JIT Long-running scripts
0 Disabled Debugging

PHP-FPM Configuration

Location

backend/docker/php/php-fpm.conf

Pool Configuration

[www]
; Unix user/group of processes
user = www-data
group = www-data

; Listen on TCP socket
listen = 0.0.0.0:9000

Process Management

; Process manager configuration
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.max_requests = 1000
Setting Value Description
pm dynamic Adjust workers based on demand
max_children 50 Maximum worker processes
start_servers 5 Initial workers on startup
min_spare_servers 3 Minimum idle workers
max_spare_servers 10 Maximum idle workers
max_requests 1000 Requests before worker respawn

Memory Calculation

Formula for max_children:

max_children = (Available RAM - Reserved RAM) / RAM per process

Example for 2GB container:

max_children = (2048MB - 512MB) / 50MB = ~30 processes

Timeouts

; Request timeout
request_terminate_timeout = 300

; Slow log threshold
request_slowlog_timeout = 10s
slowlog = /proc/self/fd/2

Health Monitoring

; Status endpoint for monitoring
pm.status_path = /fpm-status
ping.path = /fpm-ping
ping.response = pong

Security

; Clear environment
clear_env = no

; Catch workers output
catch_workers_output = yes
decorate_workers_output = no

; Limit extensions
security.limit_extensions = .php

Laravel Optimization Commands

Production Caching

# Cache configuration (requires env vars at runtime)
php artisan config:cache

# Cache routes
php artisan route:cache

# Cache views
php artisan view:cache

# Cache events
php artisan event:cache

Autoloader Optimization

# Generate optimized autoloader
composer dump-autoload --optimize --classmap-authoritative

Clear Cache (for development)

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

Performance Benchmarks

With the optimized configuration:

Metric Before After Improvement
First Request ~500ms ~100ms 5x faster
Subsequent Requests ~150ms ~30ms 5x faster
Memory per Worker ~100MB ~50MB 50% less
Throughput 200 req/s 1000+ req/s 5x higher

Monitoring OPcache

Check OPcache Status

// Add to a diagnostic endpoint
$status = opcache_get_status();
$config = opcache_get_configuration();

// Key metrics
echo "Memory used: " . $status['memory_usage']['used_memory'];
echo "Hit rate: " . $status['opcache_statistics']['opcache_hit_rate'];
echo "Cached files: " . $status['opcache_statistics']['num_cached_scripts'];

PHP-FPM Status

# Via FastCGI
SCRIPT_NAME=/fpm-status \
SCRIPT_FILENAME=/fpm-status \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000

Troubleshooting

OPcache Not Working

# Check if OPcache is enabled
php -i | grep opcache.enable

# Check loaded modules
php -m | grep OPcache

High Memory Usage

  1. Reduce pm.max_children
  2. Lower opcache.memory_consumption
  3. Check for memory leaks in code

Slow Requests

  1. Check slowlog for patterns
  2. Enable opcache.jit
  3. Increase realpath_cache_size

Next Steps