Supercharged PHP & Server Optimizations
By Josh Copeland
Josh Copeland
Socials: @OGProgammer
Remote Dev Force
Josh@RemoteDevForce.com
Table of contents
Servers
PHP
Frameworks
01
02
03
How to optimize linux servers, apache/nginx, and database servers.
Optimizing PHP FPM & Core.
What your options are for optimizing Laravel & Symfony.
Metrics
Metrics
Servers
01
Memory
Finding Memory Allocation & Utilization with βfreeβ command
free
Swap Memory
To disable or not to disable, that is the question.
free
CPU
dstat
Processes
Find what process is using a majority of the systems resources.
top
Processes
htop
Disk
df -h
Monitor Disk/Memory Usage
Disk
ulimit -n 4096
βToo many open filesβ
ulimit
vi /etc/security/limits.conf
* soft nofile 1024
* hard nofile 4096
Network Traffic
nload
Network Traffic by Process
nethogs
AWS Graphs
AWS
AWS Graphs
AWS
Web Servers
nginx/apache
Caching
Varnish Cache
PHP
02
Upgrade PHP
5 > 7 > 8
Upgrade PHP
Profile your code
Xdebug + Webgrind
Blackfire.io
Any PHP APM (NewRelic/Datadog/etc.)
See hot spots? Refactor those.
Code Profiling
Use the right data types
php -m
Double check enabled modules
php-m
php.ini
disable_functions = system, exec, shell_exec, passthru, phpinfo, show_source, highlight_file, popen, fopen_with_path, dbmopen, dbase_open, chdir, filepro, filepro_rowcount, filepro_retrieve, posix_mkfifo, pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wifcontinued, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig, pcntl_signal, pcntl_signal_get_handler, pcntl_signal_dispatch, pcntl_get_last_error, pcntl_strerror, pcntl_sigprocmask, pcntl_sigwaitinfo, pcntl_sigtimedwait, pcntl_exec, pcntl_getpriority, pcntl_setpriority, pcntl_async_signals
disable_functions
php.ini
realpath_cache_size = 4096K -> 8M
realpath_cache_ttl = 120 -> 600
This value should be increased on systems where PHP opens many files, to reflect the quantity of the file operations performed.
realpath_cache_size
php-fpm tuning
pm = dynamic -> static
pm.max_children = 10 -> memory_limit Γ· total available memory
For high traffic sites, a static amount of php-fpm workers is ideal.
dynamic is ok for low traffic or admin backend sites.
ondemand is good for cpanel/mass hosting for multiple pools that get little/no traffic.
php-fpm process management
Setting | Value |
max_children | (Total RAM β Memory used for Linux, DB, etc.) / process size |
start_servers | Number of CPU cores x 4 |
min_spare_servers | Number of CPU cores x 2 |
max_spare_servers | Same as start_servers |
Dynamic calculation
php.ini or pool.d/www.conf
memory_limit = 128M -> 512M*
Large queries, xdebug, or heavy reports will bloat memory usage.
Offload report queries to background php cli workers.
* The lower the better but symfony/laravel tend to eat up memory.
Memory limit
OPCache & JIT
40%+ Increase in speed
OPcache Ext.
PHP 5.2, 5.3, 5.4 has a PECL Extension
PHP 5.5+ requires it to be compiled as a βshared extensionβ
To use OPCache with Xdebug, you need to load OPCache before Xdebug.
opcache
OPcache + JIT - php.ini
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=500000000
opcache.jit=1235
Opcache + jit
OPcache + JIT - opcache.ini
[opcache]
opcache.enable=1
; 0 means it will check on every request
; 0 is irrelevant if opcache.validate_timestamps=0 which is desirable in production
opcache.revalidate_freq=0
opcache.validate_timestamps=1
opcache.max_accelerated_files=10000
opcache.memory_consumption=192
opcache.max_wasted_percentage=10
opcache.interned_strings_buffer=16
opcache.fast_shutdown=1
Longhorn + jit
OPCache Preload
Check your framework or find a package.
https://github.com/Laragear/Preload
https://symfony.com/blog/php-preloading-and-symfony
opcache.preload=/app/config/preload.php
Opcache preload
Database queries are the bottleneck πΎ
DB
Frameworks
03
Async php
Do you even PROD?
APP_ENV to prod
Laravel
Update!
Laravel
Debugbar
Laravel
Debugbar
Laravel
Laravel Octane uses Open Swoole, Swoole, and RoadRunner.
Octane boots your application once, keeps it in memory, and then feeds it requests at supersonic speeds.
Octane
Eloquent
if (!Cache::has('activeTeams'))
{
$teams = User::Where('status','Active')->with('Teams')->get();
Cache::put('activeTeams', $teams, Carbon::now()->addMinutes(1));
}
else{
$teams = Cache::get('activeTeams');
}
Results Cache
Symfony
Doctrine
Check your framework docs
Continue the hunt for optimizations
2pm Tomorrow
10am Tomorrow
Bring it around town.
What do you got to work with? What do you need?
What can you squeeze out of what you have?
Cache and optimize what you arenβt.
Make what you have better.
Server
Refactor
PHP
Framework
RemoteDevForce.com
We can help!