A Flame Graph is a visualization of hierarchical profiler data where the width of horizontal bars represents the proportion of time or resources spent in each function call stack. It is a critical tool for hotspot identification, allowing performance engineers to quickly see which code paths consume the most execution time on a processor like an NPU. The y-axis shows stack depth, and the x-axis spans the total profile, with each rectangle representing a function. This intuitive layout transforms raw sampling profiler or instrumentation profiler output into an actionable performance map.
Glossary
Flame Graph

What is a Flame Graph?
A Flame Graph is a hierarchical visualization of profiler data, used to identify performance bottlenecks in software, particularly for optimizing workloads on hardware accelerators like Neural Processing Units (NPUs).
For NPU acceleration, Flame Graphs are used to analyze kernel profiler data, revealing if a workload is compute bound or memory bound. They help visualize thread divergence, pipeline stalls, and inefficient memory access patterns that hinder compute throughput. By pinpointing exact functions, engineers can apply targeted optimizations like kernel fusion, loop unrolling, or memory coalescing. This data-driven approach is foundational for auto-tuning and bottleneck analysis, ensuring NPU resources are fully utilized for peak performance in AI inference and training pipelines.
Key Characteristics of Flame Graphs
Flame graphs are a hierarchical visualization of profiler data, where the width of each horizontal bar represents the proportion of time spent in a specific function call stack, enabling rapid identification of performance bottlenecks.
Hierarchical Call Stack Representation
A flame graph visualizes the call stack from bottom to top. The root of the stack (the main thread or entry point) is at the bottom. Each frame (function) is a horizontal bar. A bar's width is proportional to the time spent in that function, including all its descendants. This hierarchy allows you to see not just which function is slow, but the entire expensive code path leading to it.
- Bottom-up vs. Top-down: The standard (icicle) flame graph is top-down, showing the caller above the callee. A reverse flame graph (or bottom-up) inverts this to aggregate costs by leaf functions, useful for identifying common low-level resource consumers.
Width-Encoded Time Proportion
The fundamental metric in a flame graph is the horizontal width of each frame. This width is not absolute time but a relative proportion of the total sampled time. This encoding allows for immediate visual comparison: the widest bars represent the hottest code paths and the most significant optimization targets.
- Sampling Overhead: Because flame graphs are typically generated from sampling profilers (e.g.,
perf,DTrace), they have low overhead and provide a statistical profile of where the program spends its cycles, rather than exact instruction counts.
Color as a Secondary Dimension
Color is used as a non-quantitative visual aid to differentiate between frames or to encode an additional dimension. Common schemes include:
- Random Hue: Different colors for adjacent frames to improve visual separation.
- Library/Namespace: Color by code origin (e.g., user code vs. kernel code vs. library code).
- Performance Metric: In differential flame graphs, color can show performance regression (red) or improvement (green) between two profiles.
Color should never be the primary carrier of the performance data; that role is reserved for width.
Interactive Exploration for Root Cause
Static flame graphs are useful, but interactive exploration is key for deep analysis. Interactive features include:
- Zooming: Click on a frame to zoom into that subtree, hiding all other call paths.
- Search: Highlight all frames matching a function name, library, or pattern.
- Tooltips: Hover over a frame to see exact sample counts, percentages, and source file locations.
This interactivity transforms the graph from a static report into a diagnostic tool, allowing engineers to drill down from a broad system-wide view to a specific, costly loop or system call.
Different Flame Graph Types
While CPU time is the most common profile, the flame graph visualization can be applied to many other performance resources:
- CPU Flame Graph: The original type, showing on-CPU function time.
- Off-CPU Flame Graph: Shows time a thread was blocked (e.g., on I/O, locks, sleeping), revealing latency issues.
- Memory Flame Graph: Visualizes heap allocations or memory footprint by call site.
- Differential Flame Graph: Compares two profiles, showing which code paths increased (red) or decreased (green) in cost.
- Hot/Cold Flame Graph: Combines on-CPU and off-CPU data in a single visualization.
Integration with NPU & Hardware Profiling
For Neural Processing Unit (NPU) acceleration, flame graphs can be generated from hardware execution traces and kernel profiler data. Instead of software function calls, frames represent:
- NPU Kernels: Individual computational kernels launched.
- Memory Operations: Data transfers (H2D, D2H) and synchronization events.
- Hardware Stages: Pipeline stages, tensor operations, or vendor-specific low-level functions.
This provides a visual breakdown of the kernel execution timeline, helping identify if bottlenecks are in compute-bound kernels, memory-bound transfers, or scheduling overhead between concurrent kernels.
How Flame Graphs Work for NPU Profiling
A Flame Graph is a hierarchical visualization of profiler data used to identify performance bottlenecks in NPU-accelerated workloads.
A Flame Graph is a visualization of hierarchical profiler data where the width of horizontal bars represents the proportion of time spent in each function call stack, used to identify performance hotspots on Neural Processing Units (NPUs). Each bar, or "flame," represents a function in the call stack, with the y-axis showing stack depth and the x-axis showing the total sample count or time. This provides an immediate, intuitive view of where an application spends its cycles, distinguishing between compute-bound and memory-bound bottlenecks.
For NPU profiling, Flame Graphs are generated from sampling profiler data, such as hardware performance counter samples or execution trace snapshots. The visualization helps performance engineers quickly pinpoint inefficient kernels, excessive memory coalescing issues, or thread divergence. By analyzing the widest flames, engineers can focus optimization efforts, such as adjusting workgroup size or applying kernel fusion, to maximize compute throughput and memory bandwidth utilization on the specialized accelerator hardware.
Flame Graph vs. Other Profiling Visualizations
A comparison of profiling visualization techniques used to analyze performance bottlenecks in NPU, GPU, and CPU workloads, focusing on their suitability for identifying compute-bound vs. memory-bound issues.
| Feature / Metric | Flame Graph | Call Graph | Timeline / Trace View | Flat Profile / Top-Down |
|---|---|---|---|---|
Primary Visualization | Horizontal icicle plot | Directed graph (nodes & edges) | Chronological Gantt chart | Sorted list or table |
Core Data Representation | Aggregated call stack samples | Function call relationships | Temporal event sequence | Function-level aggregate metrics |
Best For Identifying | Widest code paths (hotspots) | Calling context & dependencies | Concurrency, stalls, overlap | Most expensive functions |
Hierarchy Display | ✅ Full stack depth | ✅ Parent/child calls | ❌ Limited (per lane) | ❌ None (flat) |
Time Metric | ✅ Proportional width (sample count) | ✅ Node/edge weight (time/calls) | ✅ Absolute start/end time | ✅ Exclusive/Inclusive time |
Memory Bound Analysis | Indirect (via width) | ❌ Poor | ✅ Direct (memory ops visible) | Indirect (via time) |
Concurrency Analysis | ❌ No | ❌ No | ✅ Excellent (parallel lanes) | ❌ No |
Overhead | Low (sampling) | Medium (instrumentation) | High (tracing) | Low (sampling) |
Ideal for NPU Kernel Tuning | ✅ High (identifies dominant ops) | Medium (see kernel launch flow) | ✅ High (see memory/compute overlap) | Medium (rank kernels) |
Frequently Asked Questions
A Flame Graph is a critical visualization tool for performance engineers. It transforms hierarchical profiling data into an intuitive, interactive diagram to pinpoint the exact functions consuming the most time in your application, particularly when optimizing for Neural Processing Units (NPUs) and other hardware accelerators.
A Flame Graph is a visualization of hierarchical profiler data where the width of horizontal bars represents the proportion of total time spent in each function call stack. It works by sampling stack traces during program execution. Each stack frame is represented as a rectangle, where the x-axis shows the profile population (time or samples) and the y-axis shows the stack depth. Functions are stacked vertically, with the caller below and the callee above. The wider a box, the more time was spent in that function or its children. This hierarchical, color-coded layout allows you to instantly identify performance hotspots (the widest bars) and understand their context within the full call tree.
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Related Terms
Flame graphs are a key tool within a broader ecosystem of performance analysis methodologies. The following terms are essential for understanding how to measure, analyze, and optimize execution on hardware accelerators like NPUs.
Performance Counter
A hardware register within a processor that counts low-level architectural events. On NPUs, these counters are crucial for moving beyond timing data to understand why a kernel is slow. Common counters include:
- Cache Misses: Counts of L1/L2 cache access failures.
- FLOPs: Floating-point operations completed.
- Memory Transactions: Volumes of data moved between hierarchy levels.
- Stall Cycles: Cycles where execution pipelines are idle. Flame graphs can be annotated with counter data to show not just where time is spent, but which hardware bottlenecks are present.
Hotspot Identification
The process of using profiling data to locate the specific functions, loops, or instructions within a program that consume the most execution time or resources. A flame graph is the quintessential hotspot identification tool because:
- Width is proportional to time or resource consumption.
- Hierarchical stack context shows the calling path to the hotspot.
- Visual pattern matching allows engineers to quickly spot the widest bars, which represent the most significant optimization targets.
Bottleneck Analysis
The systematic process of determining the primary limiting factor that restricts the overall performance of a system or kernel. Flame graphs help diagnose common bottlenecks:
- Compute-Bound: Wide bars in pure computation functions (e.g., matrix multiplications).
- Memory-Bound: Wide bars in memory copy routines or functions waiting on data.
- Synchronization-Bound: Wide bars in lock or barrier functions. This analysis moves from where time is spent (the hotspot) to why it is spent there, guiding the selection of appropriate optimization strategies.
Execution Trace
A chronological, detailed record of the sequence of instructions, memory accesses, and function calls executed by a program. While a flame graph shows aggregated statistical samples, an execution trace provides a deterministic, step-by-step replay of execution. Key differences:
- Flame Graph: Statistical, aggregated, low-overhead. Answers "Where is the time spent?"
- Execution Trace: Deterministic, sequential, high-overhead. Answers "What was the exact order of events?" Traces are used for debugging correctness, while flame graphs are for performance profiling.
Sampling Profiler
A profiling method that periodically interrupts program execution (e.g., via a timer or hardware event) to record the current program counter and call stack. This statistical approach is the primary data collection method for CPU flame graphs. Characteristics include:
- Low Overhead: Typically 1-2% slowdown.
- Statistical Accuracy: Provides a representative picture of where time is spent.
- System-Wide: Can profile the entire system, not just a single application. The sequence of collected stack samples is then aggregated and visualized to create the flame graph.

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us