How to Use DDEV XHProf for PHP Performance Profiling: A Complete Guide

DDEV provides built-in XHProf support through the ddev xhprof command, which automatically configures the PHP extension, injects profiling collectors via auto_prepend_file, and stores run data in your project directory for analysis.

DDEV ships with native support for the XHProf profiling extension, enabling detailed function-level performance analysis for PHP applications without manual configuration. By leveraging the ddev xhprof project command and container-aware architecture, developers can capture, store, and analyze profiling data consistently across local, CI, and staging environments.

How DDEV XHProf Integration Works

DDEV implements XHProf as a project-level command suite that handles extension loading, web server configuration, and data collection automatically. The architecture consists of several coordinated components:

When active, XHProf writes run files (xhprof_*.raw) to your project's .ddev/xhprof/ directory, making data version-controllable and shareable between team members.

Enabling XHProf for Your Project

To start profiling, enable the XHProf mode for your current DDEV project. This command updates the global configuration, copies the xhprof directory structure into your project, and restarts the web container to load the PHP extension.

ddev xhprof enable

The command modifies .ddev/global_config.yaml through the logic in pkg/globalconfig/xhprof_mode.go, then executes the enable scripts that configure the PHP auto_prepend_file directive. Once enabled, every PHP request (web or CLI) automatically triggers data collection.

Collecting Profiling Data

Profiling Web Requests

After enabling XHProf, simply visit any page of your application through the browser:


# The site is now profiling every request

open https://myproject.ddev.site

Each request generates a raw profiling file in .ddev/xhprof/. The xhprof_prepend.php script handles initialization and cleanup automatically, ensuring the run file is written to disk when the request completes.

Profiling CLI Scripts

For command-line PHP execution, use the ddev xhprof run wrapper to execute a script while capturing performance data:

ddev xhprof run php -d memory_limit=2G scripts/heavy_task.php

This command runs your script with the XHProf extension active and outputs the location of the generated raw file (e.g., .ddev/xhprof/xhprof_5f8c3a2e9d3b4.raw).

Direct Container Execution

Alternatively, execute PHP commands inside the container while the extension is enabled:

ddev exec php -r 'include "index.php";'

Analyzing Profiling Results

Raw File Inspection

List and inspect the generated profiling runs directly:

ls .ddev/xhprof/*.raw

These raw files contain serialized XHProf data that can be processed by analysis tools or viewed with the xhprof_html interface if installed locally.

Visualizing with XHGui

For graphical analysis, point an XHGui instance at your profiling directory. Mount the DDEV xhprof folder into a Dockerized XHGui container:

docker run -d \
  -v $(pwd)/.ddev/xhprof:/tmp/xhprof \
  -p 8080:80 xhgui/xhgui

Access http://localhost:8080 to browse call graphs, inclusive/exclusive function costs, and flame charts. XHGui reads the raw files directly from the mounted directory.

Key Configuration Files

Understanding the source implementation helps troubleshoot edge cases:

File Purpose
pkg/ddevapp/xhprof_xhgui.go Contains the main command logic for ddev xhprof enable, disable, and run subcommands.
pkg/globalconfig/xhprof_mode.go Handles persistence of the XHProf enabled state in global configuration.
containers/ddev-php-base/ddev-php-files/etc/php/8.2/mods-available/xhprof.ini PHP 8.2 extension configuration; similar files exist for other supported versions.
containers/ddev-webserver/ddev-webserver-base-files/usr/local/bin/enable_xhprof Shell script executed inside the container to activate the extension and prepend file.
containers/ddev-webserver/ddev-webserver-base-files/usr/local/bin/xhprof/xhprof_prepend.php The PHP script injected at the start of every request to manage profiling lifecycle.
containers/ddev-webserver/ddev-webserver-base-files/etc/nginx/common.d/xhprof.conf Nginx rules exposing the .ddev/xhprof directory via the web server.
pkg/ddevapp/xhprof_xhgui_test.go Automated test suite verifying correct directory creation and extension toggling.

Disabling XHProf

When profiling is complete, disable the extension to eliminate performance overhead:

ddev xhprof disable

This removes the auto_prepend_file directive, stops further profiling, and cleans up the temporary configuration. Optionally, clear old run files:

rm -rf .ddev/xhprof/*

Summary

  • Zero-configuration setup – The ddev xhprof command handles extension installation, PHP ini configuration, and web server rules automatically.
  • Container-native storage – Profiling data resides in .ddev/xhprof/, making it environment-consistent and version-control friendly.
  • Dual-mode profiling – Supports both web requests (via auto_prepend_file) and CLI scripts (via ddev xhprof run).
  • XHGui compatible – Raw output files work with standard visualization tools for call graphs and flame charts.
  • Clean teardown – The ddev xhprof disable command reverses all changes without manual file editing.

Frequently Asked Questions

How do I enable XHProf profiling in DDEV?

Run ddev xhprof enable in your project directory. This command updates the global configuration through pkg/globalconfig/xhprof_mode.go, restarts your web container, and activates the PHP extension via the helper scripts in containers/ddev-webserver/ddev-webserver-base-files/usr/local/bin/.

Where does DDEV store XHProf profiling data?

DDEV writes raw profiling files to the .ddev/xhprof/ directory inside your project root. The xhprof_prepend.php script generates files named xhprof_*.raw containing serialized performance data for each request.

Can I profile CLI scripts with DDEV XHProf?

Yes. Use the ddev xhprof run command followed by your script execution. This wrapper ensures the XHProf extension is active during the command's lifecycle and reports the output file location upon completion.

Does enabling XHProf affect production deployments?

No. DDEV XHProf is a local development feature controlled by the xhprof_mode flag in your global configuration. The extension and auto_prepend_file directives only exist within DDEV containers and do not modify your production codebase or configurations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →