| title | PHP Performance Guidelines |
|---|---|
| scope | php |
- Enable OPcache in production (it is included with PHP)
- Key settings:
opcache.enable=1opcache.memory_consumption=256opcache.max_accelerated_files=20000opcache.validate_timestamps=0in production (restart/clear cache on deploy)opcache.jit=1255for PHP 8.0+ JIT compilation
- Use
opcache.preloadto load frequently used classes into shared memory - Preload interfaces, abstract classes, and commonly used value objects
- Generate the preload script as part of the build process
- Use generators (
yield) for processing large datasets instead of loading everything into memory:
function readLargeFile(string $path): Generator
{
$handle = fopen($path, 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
fclose($handle);
}- Use
SplFixedArrayfor large fixed-size collections - Unset large variables when no longer needed in long-running processes
- Monitor memory with
memory_get_usage()andmemory_get_peak_usage()
- Eager-load relationships instead of lazy-loading in loops
- Use JOINs or batch queries for related data
- Monitor query count in development (e.g., Laravel Debugbar, Symfony Profiler)
- Add indexes for columns used in WHERE, JOIN, ORDER BY
- Use
EXPLAINto analyze slow queries - Prefer specific column selection over
SELECT * - Use pagination for large result sets
- Cache frequently accessed, rarely changing data
- Use PSR-6 or PSR-16 cache interfaces for portability
- Cache layers (from fastest to slowest):
- OPcache (bytecode)
- APCu (in-process key-value)
- Redis/Memcached (shared, network)
- Filesystem cache
- Cache invalidation strategy: TTL-based or event-based (prefer event-based for consistency)
- Use
str_contains(),str_starts_with(),str_ends_with()(PHP 8.0+) instead ofstrpos()hacks - Use
array_key_exists()for key checks,in_array()with strict mode (trueas third argument) - For large lookups, flip arrays (
array_flip()) and useisset()instead ofin_array() - Use
implode()/explode()instead of manual string concatenation in loops
- Use Composer's optimized autoloader in production:
composer dump-autoload --optimize --classmap-authoritative - Keep
composer.jsonautoload configuration clean and accurate
- Reset state between iterations (clear entity managers, release connections)
- Implement graceful shutdown for queue workers
- Monitor memory leaks with
memory_get_usage() - Use connection pooling for database connections (e.g., with Swoole or RoadRunner)
- Use Xdebug profiler or Blackfire for identifying bottlenecks
- Profile in conditions close to production
- Focus on the critical path first — optimize what matters