A WordPress site usually comprises a theme and many plugins. If loading speeds and server load are fine for you, congratulations. Otherwise, you have to profile your WordPress-based application. Simply put, profiling means to measure how much CPU time and memory each executed function took. Let’s say you create a custom function to count from 1 to 1000. After running a PHP profiling tool, you would find out that your function took 1 millisecond of CPU time and 100 bytes of memory to complete (made-up numbers). Due to the fact that we are talking about profiling the WordPress and its plugins plus a theme, we need a high-quality software to do it. xhprof, originally developed by Facebook, is the PHP profiler. In our guide, I’ll walk you through steps necessary to install, configure and run xhprof on your WordPress site.
Step one — install xhprof PHP extension
Before we can profile anything, xhprof PHP extension has to be installed and enabled in our php.ini
configuration file. If you have homebrew on your Mac, running
brew install xhprof
in your command line might be good enough. Unfortunately, I received several errors during xhprof.so
extension compilation. Looking for a solution, we can compile xhprof as PHP’s pecl extension.
pecl install xhprof
Note: if you installed PHP through homebrew, pecl is available to you as a command line tool.
Next thing to do is to enable xhprof extension in our php.ini
config file. Locate your php.ini
file (/usr/local/etc/php/5.6/php.ini
in my case) and add
[xhprof] extension= xhprof.output_dir="/var/tmp/xhprof"
to the end of the file. /usr/local/Cellar/php56/5.6.5/lib/php/extensions/debug-non-zts-20131226/xhprof.so
is the
on my OS. We can find the path in the logs of xhprof compilation process.
If you use Apache HTTP with mod_php, restart the Apache server. In case you use Nginx for serving your WordPress site, you probably use PHP-FPM as your FastCGI server. In that case, you need to restart PHP-FPM, not Nginx.
After restarting Apache or PHP-FPM, run php -i
in your console or call phpinfo();
to verify if xhprof is working. Look for xhprof
in its output.
This step was the hardest one. Let’s have some fun now!
Step two — download xhprof XHGUI
XHGUI is a graphical companion to xhprof profiler. Tuurlijk’s XHGUI is my most favorite one.


XHGUI stores every single profiler run in a database. They can be then compared side-by-side to see the difference in loading speeds and memory usage.
Download and unzip it somewhere. Note down the path to the xhprof_html
directory located in the unzipped folder. We’ll refer to it later on.
Step three — configure Apache HTTP or Nginx virtual hosts for XHGUI
Create a new virtual host for the XHGUI. Point the DocumentRoot
(Apache) or root
(Nginx) to the xhprof_html
folder I mentioned in the second step. For example:
DocumentRoot "/Users/lamosty/temp/xhprof/xhprof_html" ServerName dev.x AllowOverride All Order allow,deny Allow from all
for Apache vhost;
or
server { listen 80; server_name dev.x; root /Users/lamosty/dev/xhprof/xhprof_html; index index.php index.html; [...]
for Nginx vhost.
I’ve called the host dev.x so it’s easier to type it into the browser. But for that to work we need to edit /etc/hosts
and add
127.0.0.1 dev.x
there.
Step four — create a database for XHGUI
XHGUI uses MySQL to store profiling results. Create a new database (I called it xhprof). Navigate to
/xhprof_lib/utils/Db
and open your PHP MySQL connector of choice. I chose Pdo, so I opened Pdo.php
in that folder. In that file you will find a SQL query for creating a details table for XHGUI. Run this query in the database you previously created (xhprof in my case).
Step five — configure XHGUI
Open
/xhprof_lib/config.sample.php
Type in your MySQL credentials (user, pass), database for xhprof (my case xhprof), url for XHGUI (in our case http://dev.x
) and dbsocket as a path to your MySQL socket (in my case /tmp/mysql.sock
on OS X Yosemite).
Configure $_xhprof['serializer']
to JSON
. On line 56, we can see $_xhprof['display'] = FALSE;
. Change it to true, so we get a nice link to the XHGUI profiling statistics after running xhprof on our WordPress site.
If you need to configure anything else and you know what you are doing, feel free to do so.
Step six — prepend every request with xhprof’s header.php file
In order for xhprof to start working, it needs a PHP file called
/external/header.php
to be prepended to each request we want to profile. Therefore, we need to add a line of configuration to Apache or Nginx virtual hosts of our WordPress website we want to profile.
Apache:
php_admin_value auto_prepend_file "/external/header.php"
Nginx:
fastcgi_param PHP_VALUE "auto_prepend_file=/external/header.php";
is the absolute path to the folder where we unzipped the downloaded XHGUI.
Step seven — install XHProf helper Chrome Extension
By default, xhprof is configured to profile a website only if cookie with key _profile
is set to 1
. There is a handy Chrome Extension aptly named XHProf helper. If you are not using Google Chrome, try to find a similar extension or simply set that cookie manually.
Install the extension and continue to the last step.
Step eight — run it on your WordPress site
After getting the XHProf helper extension into your Chrome, an icon

should appear to the right of the search bar. Navigate to your WordPress site’s homepage (or any other subpage), click on the icon (it should turn to green) and reload the page. The profiler should have run and link to profiler output
Optional steps
Do you want a pretty call graphs? Such as
We need to install Graphviz to be able to create such nice call graphs. Graphviz includes dot
command line tool. Open XHGUI config.php
mentioned before and uncomment lines 36-38. Rendering call graphs should work after that.
Concluding remarks
Phew, this was a pretty tedious tutorial. However, if you accomplished to get xhprof working, congratulations. Profiling your WordPress-powered website is going to be fun again.