Docs / Performance Optimization / How to Profile PHP Application Performance with Xdebug

How to Profile PHP Application Performance with Xdebug

By Admin · Mar 2, 2026 · Updated Apr 24, 2026 · 29 views · 3 min read

How to Profile PHP Application Performance with Xdebug

Xdebug is the standard profiling tool for PHP applications, providing detailed execution traces and cachegrind-format profiles that reveal exactly where your application spends its time. On your Breeze server, Xdebug profiling helps identify slow functions, excessive database calls, and memory-hungry operations.

Installing Xdebug

sudo apt install -y php-xdebug

Verify the installation:

php -v
# Should show "with Xdebug" in the output

php -m | grep xdebug

Configuring Xdebug for Profiling

Edit the Xdebug configuration file (typically at /etc/php/8.2/mods-available/xdebug.ini):

; Enable profiling mode
xdebug.mode = profile

; Trigger profiling only when requested (recommended)
xdebug.start_with_request = trigger

; Output directory for profile files
xdebug.output_dir = /tmp/xdebug-profiles

; Profile filename format
xdebug.profiler_output_name = cachegrind.out.%t.%p

Create the output directory:

sudo mkdir -p /tmp/xdebug-profiles
sudo chmod 777 /tmp/xdebug-profiles

Restart PHP-FPM to apply changes:

sudo systemctl restart php8.2-fpm

Triggering a Profile

With start_with_request = trigger, profiling only activates when you add a special parameter:

# Via browser - add XDEBUG_PROFILE to the URL
https://yourdomain.com/slow-page?XDEBUG_PROFILE=1

# Via curl
curl -b "XDEBUG_PROFILE=1" https://yourdomain.com/api/endpoint

# Via cookie (install a browser extension like Xdebug Helper)

Analyzing Profile Output

Profile files are in cachegrind format. Use these tools to visualize them:

# Install KCacheGrind (Linux GUI)
sudo apt install -y kcachegrind

# Open a profile file
kcachegrind /tmp/xdebug-profiles/cachegrind.out.1234.5678

# For command-line analysis, use webgrind or qcachegrind

Alternatively, use Webgrind, a web-based viewer you can run directly on your Breeze server:

cd /var/www
git clone https://github.com/jokkedk/webgrind.git
# Access via browser at http://yourdomain.com/webgrind/

Understanding the Profile Data

  • Self time — time spent executing the function itself, excluding calls to other functions
  • Inclusive time — total time including all child function calls
  • Call count — how many times a function was invoked (high counts indicate loops or recursion)
  • Callers/Callees — the call graph showing which functions call which

Common Performance Patterns to Look For

  • N+1 queries — a database fetch function called hundreds of times inside a loop; fix with eager loading or JOINs
  • Excessive autoloadingspl_autoload appearing high in the profile; use Composer's classmap optimization
  • String concatenation in loops — build arrays and implode instead of repeated concatenation
  • Unoptimized regexpreg_match with backtracking-heavy patterns on large inputs
  • Missing opcode cache — ensure OPcache is enabled in production

Production Safety

Never leave Xdebug profiling enabled on a production server. It adds significant overhead:

# Disable Xdebug in production
sudo phpdismod xdebug
sudo systemctl restart php8.2-fpm

# Or keep Xdebug installed but set mode to off
xdebug.mode = off

For production profiling, consider lighter alternatives like tideways or SPX that have lower overhead. For quick one-off profiling, use the trigger mode and remove it immediately after collecting data.

Quick Profiling with SPX

SPX is a lighter alternative built into PHP:

sudo pecl install spx
echo "extension=spx.so" | sudo tee /etc/php/8.2/mods-available/spx.ini
sudo phpenmod spx

Access the built-in web UI at /?SPX_KEY=dev&SPX_UI_URI=/ for real-time flame graphs without cachegrind files.

Was this article helpful?