Flame Graphs for PHP Profiling
debt(d7/e3/b3/t5)
Closest to 'only careful code review or runtime testing' (d7), because the misuse here is the *absence* of flame graphs — optimising based on guesswork rather than profiling data. Tools like Blackfire, Xdebug, Tideways, and Speedscope are available (from detection_hints.tools) but only surface problems when someone actively runs them; no automated check flags 'you are optimising without profiling evidence'. The gap is only visible via code review or performance complaints in production.
Closest to 'simple parameterised fix' (e3), grounded in quick_fix: adopting Blackfire or Xdebug+Speedscope is a small setup step (install tool, capture profile, open flamegraph). It's more than a one-line patch because it involves configuring a profiling tool and interpreting output, but it doesn't require touching multiple files — it's a localised workflow change rather than a code refactor.
Closest to 'localised tax' (b3), because the choice to adopt (or neglect) flame graph profiling primarily affects the performance-investigation workflow rather than spreading structural weight across the codebase. Applies to web and cli contexts broadly, but the debt is a workflow/tooling gap, not a load-bearing architectural choice that shapes every future change.
Closest to 'notable trap' (t5), directly grounded in the misconception field: developers commonly believe the *top* of the flame graph shows the slowest calls, when actually the top is the deepest stack frame and the *width* near the bottom reveals bottlenecks. This is a documented, well-known gotcha (also confirmed by common_mistakes: 'Optimising tall thin flames') that most developers encounter and learn — a real but correctable misreading of the visualisation.
Also Known As
TL;DR
Explanation
Flame graphs (Brendan Gregg) visualise profiling data as stacked rectangles: x-axis represents cumulative time (width = % of samples), y-axis is call depth. Wide blocks at the bottom are the largest consumers. For PHP: Xdebug traces processed by flamegraph.pl, Blackfire profiler's built-in interactive UI, Tideways, or the lightweight SPX profiler. Sampling profilers (Blackfire, Pyroscope) have negligible overhead and can run in production. Instrumented profilers (Xdebug full trace) are precise but too slow for production. A 30-second flame graph from a live server will reveal more actionable insight than hours of reading code.
Common Misconception
Why It Matters
Common Mistakes
- Not using flame graphs for PHP performance issues — running Xdebug profiler + speedscope/flamegraph.pl is a low-effort high-value analysis.
- Profiling in development instead of staging — the workload and data size differ significantly.
- Optimising tall thin flames — wide flames (broad base) indicate the real hot paths.
- Not sampling long enough — short profiles miss infrequent but expensive operations.
Code Examples
# Profiling with xdebug trace — no flame graph:
; php.ini:
xdebug.mode=trace
xdebug.output_dir=/tmp/xdebug
; Output: massive trace file, hard to analyse manually
; Better — use SPX or Blackfire which generate flame graphs automatically:
; SPX_ENABLED=1 SPX_FP_LIVE=1 in environment
// Generate flamegraph with SPX (easiest for PHP)
// 1. Install: https://github.com/NoiseByNorthwest/php-spx
// 2. Add to php.ini: extension=spx.so; spx.http_enabled=1; spx.http_key=dev
// 3. Append ?SPX_KEY=dev&SPX_ENABLED=1 to any URL
// 4. View flamegraph at /_spx
// Or with Blackfire:
// 1. Install Blackfire agent + PHP probe
// 2. blackfire curl https://yourapp.local/heavy-endpoint
// 3. Flamegraph available in Blackfire dashboard — click to drill into any frame
// Read a flamegraph:
// X axis = time (not chronological — alphabetical by call)
// Y axis = call stack depth
// Widest boxes = most cumulative time — optimise these first