Finding and fixing performance bottlenecks in PHP web applications can be both time-consuming and difficult. Fortunately, free tools like Xdebug and Webgrind allow you to easily find and visualize bottlenecks in your PHP scripts.
Webgrind is an Xdebug profiling web frontend in PHP5. It implements a subset of the features of kcachegrind and installs in seconds and works on all platforms.–Webgrind
Anyone who has ever needed to profile code is probably familiar with KcacheGrind (a profile data visualization tool). KcacheGrind provides a way to visualize the profile data from a program execution, allowing you to quickly and easily see where the program is spending its time. Knowing where the execution bottlenecks are allows you to focus your optimization efforts in the correct places.
For a long time, the Xdebug extension for PHP has been able to (among other things) dump execution profile information to disk in a format that is usable by KcacheGrind, which is great if you are running Linux with KDE.
The webgrind project provides a web-based replacement for KcacheGrind that can be installed on any operating system, allowing you to visualize a portion of the Xdebug profiling data through a browser.

Installation
Before using webgrind, you must first install Xdebug.
Installing webgrind is pretty simple:
- Download webgrind
- Unzip webgrind in your web server’s document root
- Configure Xdebug and webgrind
- Point your browser to where you installed webgrind
Configuration
Unfortunately, webgrind does not often work “out-of-the-box”… There are a few configuration details that need to be dealt with in order to start profiling your code. The following PHP configuration directives can be used to control the behavior of Xcebug:
- xdebug.profiler_enable
- This directive actually turns on Xdebug’s internal profiler. You must set this to
1in order to have Xdebug actually produce output for webgrind to analyze. - xdebug.profiler_enable_trigger
-
If you enable this option, profiles will only be generated if you pass a GET/POST parameter or cookie with the name
XDEBUG_PROFILE, e.g.,http://localhost/script.php?XDEBUG_PROFILE. You must not enablexdebug.profiler_enableif you use this option. - xdebug.profiler_output_dir
- This directive tells Xdebug where to put the profile data. By default, it is set to ‘/tmp’, which is usually fine. If you want, you can probably omit this from your Xdebug configuration.
- xdebug.profiler_output_name
- This value tells Xdebug how to create filenames for the data it writes to disk. By default, the value is set to
cachegrind.out.%p, where%pwill be replaced with the process ID. This is bad, and you will definitely need to change it. The problem is that Apache processes serve multiple requests, so each request in a given process will overwrite the profiling data from previous requests. Other possible format specifiers can be used. - xdebug.profiler_append
-
Enabling this option will cause xdebug to append data to the output file if it already exists (the default behavior is to overwrite the output file). This is a handy option if you need to average out the profiling data over multiple script executions. In that case, be sure to set
xdebug.profiler_output_nameusing a format that will ensure that each successive page load uses the same profiler output name, e.g.,cachegrind.out.%s.
Assuming you have already loaded the Xdebug extension, the following additional PHP configuration directives should be a good starting point for you:
xdebug.profiler_enable = 1 xdebug.profiler_output_name = cachegrind.out.%t.%p
That’s it, you should be ready to profile your PHP code with Xdebug and Cachegrind!



Thanks for the clear explanation.
Here are the lines to add in your php.ini after the loading xdebug line:
xdebug.profiler_enable=On
; Provide the appropriate path of your tmp directory
xdebug.profiler_output_dir=”/usr/local/php5/tmp”
xdebug.profiler_append=On
xdebug.profiler_output_name = cachegrind.out.%t.%p
; Use XDEBUG_PROFILE in GET or POST parameter to activate the profile log
; ex: URL: test.php?XDEBUG_PROFILE
xdebug.profiler_enable_trigger=On
To activate the profiler for a script you have to give a parameter in the url:
ex. http://localhost/script.php?XDEBUG_PROFILE
And the profiler will be realized.
Thanks for the additional information Diglin, I’ve updated the post to include information on
xdebug_profiler_appendandxdebug_profiler_enable_trigger.Hi, I’ve got a huge problem with webgrind. I got the xdebug installed and working – it creates its output files im predefinied directory. But i can’t get webgrind to work – it doeasn’t see the xdebug output files, althought they’re are there. Help, i’m stuck
to Piotr:
Had the same problem, just realized that if xdebug.profiler_enable is set to 1, debugging is done on webgrind and it cannot read the cachegrind files because they are files in use.
Profiler must not run on webgrind.
Hope it helps!
@Piotr:
What value do you have for your
profiler_output_nameconfiguration parameter? I had a similar issue as well, and found that this parameter needs to be set so that loads of webgrind itself never use the same output filename as the page you are trying to profile.You can either conditionally profile pages using
profiler_enable = 0andprofile_enable_trigger = 1as Jim suggests, or you can useprofiler_output_name = cachegrind.out.%t.%pI’d definitely be interested in hearing if those options do not work for you!
Hi
I got it to work with the following configuration in both /apache/bin/php.ini AND /php/php.ini:
zend_extension_ts=”\path\to\ext\php_xdebug.dll”
xdebug.remote_enable=true
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.profiler_enable=1
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.profiler_output_dir=”C:\xampp\tmp”
What value do you have for your profiler_output_name configuration parameter? I had a similar issue as well, and found that this parameter needs to be set so that loads of webgrind itself never use the same output filename as the page you are trying to profile.
I usually use
cachegrind.out.%t.%pwhen I want one output file per script run, but if I want to run a script multiple times and see the aggregate numbers I usecachegrind.out.%sand setxdebug.profiler_append = onI’m on a ubuntu box, I’ve configured xdebug exactly as above
xdebug.profiler_output_name=cachegrind.out.%t.%p
xdebug.profiler_append=On
yet, when running localhost/webgrind, it only lists of the .out files from this script
/usr/share/obm/www/cron/cron.php
So frustrated….
@Steve: Do you also have
xdebug.profiler_enable=1in your configuration?Nice to know, for different cachegrind files per host you can use %H in the profiler_output_name, according to http://www.xdebug.org/docs/all_settings#trace_output_name
можно в Гугле еще поискать..
Hello,
I am running Ubuntu 9.10 and have installed everything as stated above. Everything seems to be working to the point that the grind files are generated. However when I go into webgrinds web interface and click update it just shows a message telling me to select a grind file. No matter which file I choose I get the same message. I have verified that the grind files actually contain data. I am not sure if there is a permissions problem reading them or not.
jocrawfo@jcrawford:~/installed/webgrind/grinds$ namei -m ~/installed/webgrind/grinds/cachegrind.out.1268144184.18372
f: /home/jocrawfo/installed/webgrind/grinds/cachegrind.out.1268144184.18372
drwxr-xr-x /
drwxr-xr-x home
drwxrwxr-x jocrawfo
drwxr-xr-x installed
drwxr-xr-x webgrind
drwxrwxrwx grinds
jocrawfo@jcrawford:~/installed/webgrind$ ls -la | grep grinds
drwxrwxr-x 2 www-data www-data 4096 2010-03-09 09:26 grinds
Any assistance would be appreciated.
Thanks,
Joseph Crawford
This is slightly off topic, but maybe you can help. I have installed XDebug for php5.3.2VC9TS on a windows 7 box and I use a virtual Ubuntu 9.04 with kcachegrind installed to produce the visuals.
But when I enable the profiler I get not output in the browser. I do get output files that I can produce visuals of. But the browser says the connection was reinitialized during the request and refuses output.
Any idea’s?
This is in my php.ini:
[XDebug]
zend_extension=d:\php532\ext\php_xdebug-2.0.5-5.3-vc9.dll ; if xdebug enabled, webserver doesn’t output
xdebug.profiler_enable=1
xdebug.profiler_output_dir=d:\tmp
xdebug.profiler_output_name = cachegrind.out.%t.%p
Also please do not forget Webgrind may have no permissions to read profiler output files. For example if these files are located not in Webgrind server root.
So, the default php open_basedir restriction may be in effect.
If so, add to configuration of VirtualHost
php_admin_value open_basedir none
Or in similar way set profiler output files accessible from webgrind installation.
Thanks for all the help above.
I’ve been hair pulling for the last 2 days to get Webgrind running, receiving a file read error on xdebug.profiler_output_dir.
The solution (for me at least): changing xdebug.remote_host from ‘localhost’ to 127.0.0.1. It’s probably written somewhere but I suffer from the disease of !RTFM
Hi Dear,
I am completely new to webgrind and Xdebug so want some help from you guys.
First clear me the os in which i should install the webgrind and then
the file and location in which we have to make the modifications.
Note:I am currently using wamp server.
Hi Ali,
Which Os are you using? Linux, Windows or Apple……?
Thanks for posting man, very helpful.
There is now a lower overhead module to profile PHP scripts: http://exteon.ro/en/products/php-tools/web3tracer
Hi,
We have a server side PHP script. Majorly, it interacts with MySQL Database (30+ tables) and performs some custom/business logic.
For various reasons, we need to run 100+ instances of this script as a cron process. So, any given point of time, there are 100+ cron jobs running.
We observe that ‘php’ is being placed always in the 1st 3 places in the output of ‘top’ command.
We want to profile/debug this script in real time (production server) when 100+ instances are running and find out the bottlenecks.
Please help how we can proceed. your inputs are highly valuable to us.
Hi,
In reply to Satya and this article: we have built a PHP profiler on top of XHProf that also uses callgrind output format. The main advantage over XDebug is hugely lower overhead and better recursive function handling, as well as XHProf-style profiling begin and end functions, enabling automated unit testing. You can see it at http://www.exteon.ro/en/products/php-tools/web3tracer
Hi,
I have the same problem as Joseph Crawford. Could somebody give me any advice for solving this problem?
Any help will be greatly appreciated.
Attn Joseph Crawford & Derek:
This is most likely because your webgrind output directory either doesn’t exist or doesn’t have the correct ownership/permissions.
Open up webgrind’s config.php and check what the storageDir is. Then check the ownership and permissions of that directory, and make sure your apache user (eg, www-data) can write to it.