Your PHP site is slow? Time to look under the hood
\n\nHave you ever waited for a page to load longer than it takes to drink your morning coffee? A familiar pain. PHP is a powerful language, but without proper configuration, it can turn into a turtle. In this article, we won't give boring lectures. We'll take real code, profile it, find bottlenecks, and speed it up so much that your server will thank you.
\n\nWe'll talk about PHP performance — from simple measurements to deep profiling. You'll learn how to find problem areas using Xdebug and Blackfire, and which optimization methods actually work. Let's go!
\n\nStep 1. Measure everything: from microseconds to megabytes
\n\nBefore optimizing anything, you need to understand where the slowdown is. Intuition often fails. Let's use tools.
\n\nThe simplest way: microtime(true)
\n\nFor a quick check of a code snippet, good old microtime() will do. Not elegant, but it works.
<?php\n$start = microtime(true);\n\n// Your slow code\n$data = [];\nfor ($i = 0; $i < 100000; $i++) {\n $data[] = md5($i . 'salt');\n}\n\n$end = microtime(true);\necho 'Execution time: ' . round(($end - $start) * 1000, 2) . ' ms';\n?>\n\nThis method is good for a rough estimate. But when a project grows, you need serious tools.
\n\nXdebug — your personal detective
\n\nXdebug is the de facto standard for PHP profiling. It generates cachegrind files that can be opened in KCachegrind (Linux) or QCachegrind (Mac/Windows).
\n\nInstallation via pecl:
\npecl install xdebug\n\nEnable profiling in php.ini:
\nxdebug.mode = profile\nxdebug.output_dir = /tmp/profiling\n\nAfter running the script, a file will appear in the folder. Open it in QCachegrind — you'll see which function consumed the most time. Often a surprise: not the database, but simple string processing in a loop.
\n\nBlackfire — for those who love beautiful dashboards
\n\nBlackfire from SensioLabs (creators of Symfony) is a cloud profiler. It shows not only time but also the number of calls, memory, I/O. It integrates with PHPUnit, Symfony, Laravel.
\n\nExample usage from the command line:
\nblackfire run php myscript.php\n\nYou'll get a link to a web report with visualization. Convenient for finding PHP performance bottlenecks.
\n\nStep 2. Common problems and their solutions
\n\nNow that we know how to profile, let's look at common pitfalls.
\n\nProblem 1: N+1 queries in a loop
\n\nA classic. You get a list of users, and then in a loop, you make a database query for each one.
\n\nSlow code:
\n<?php\n$users = $db->query('SELECT id FROM users LIMIT 100');\nforeach ($users as $user) {\n $orders = $db->query("SELECT * FROM orders WHERE user_id = {$user['id']}");\n // ...\n}\n?>\n\nOptimization:
\n<?php\n$users = $db->query('SELECT id FROM users LIMIT 100');\n$ids = array_column($users, 'id');\n$orders = $db->query('SELECT * FROM orders WHERE user_id IN (' . implode(',', $ids) . ')');\n// Group by user_id\n$grouped = [];\nforeach ($orders as $order) {\n $grouped[$order['user_id']][] = $order;\n}\n?>\n\nResult: 100 queries turned into 2. PHP application performance increases many times over.
\n\nProblem 2: Inefficient loops and string operations
\n\nString concatenation in a loop is evil. Use arrays and implode().
<?php\n// Bad\n$result = '';\nfor ($i = 0; $i < 10000; $i++) {\n $result .= 'item' . $i . ',';\n}\n\n// Good\n$parts = [];\nfor ($i =