# Debugging Node.js Performance with AI

I’ve been improving the performance of Node.js applications for the last decade. I know for a fact that performance debugging is hard, and I’ve often ended up creating my own tools. This is one of those times.

How often have you captured a CPU profile, stared at a flamegraph, and tried to make sense of thousands of stack frames? What if your AI assistant could help you understand exactly where your application is spending time?

Today, we’re releasing a new feature in [@platformatic/flame](https://github.com/platformatic/flame) that generates LLM-friendly markdown analysis alongside your flamegraphs. Now, when you profile your Node.js application, you get three outputs:

* Binary pprof data (.pb) - for tooling compatibility
    
* Interactive HTML flamegraph (.html) - for visual exploration
    
* **Markdown analysis** (.md) - for AI-assisted debugging
    

This means you can drop your profile analysis directly into Cursor, Claude Code, OpenCode, or any AI assistant and get intelligent insights about your application’s performance characteristics.

## **The Problem with Traditional Profiling**

Flamegraphs are incredibly powerful visualization tools, but they have limitations:

1. **They require expertise to interpret** - Understanding which stack frames matter takes experience.
    
2. **They don’t prioritize hotspots** - You see everything, but the critical bottlenecks aren’t highlighted.
    
3. **They’re not searchable by AI** - You can’t paste an SVG into ChatGPT and ask “what’s slow?”
    

We built Flame to make profiling accessible, and this update takes it a step further by making profile data consumable by AI assistants.

## **How It Works**

When you run Flame, it now automatically generates a markdown file with structured hotspot analysis:

```bash
# Profile your application
flame run server.js

# When you stop the app (Ctrl-C), you'll see:
# 🔥 CPU profile written to: cpu-profile-2025-01-21T12-00-00-000Z.pb
# 🔥 CPU flamegraph generated: cpu-profile-2025-01-21T12-00-00-000Z.html
# 🔥 CPU markdown generated: cpu-profile-2025-01-21T12-00-00-000Z.md
# 🔥 Heap profile written to: heap-profile-2025-01-21T12-00-00-000Z.pb
# 🔥 Heap flamegraph generated: heap-profile-2025-01-21T12-00-00-000Z.html
# 🔥 Heap markdown generated: heap-profile-2025-01-21T12-00-00-000Z.md
```

The markdown output contains a structured analysis of your profile:

```bash
# CPU Profile Analysis: cpu-profile-2025-01-21T12-00-00-000Z.pb

## Summary
- Total samples: 1,234
- Duration: 10.5s
- Sample rate: 99 Hz

## Top Hotspots

| Rank | Function | File | Self Time | Total Time |
|------|----------|------|-----------|------------|
| 1 | processRequest | src/handler.js:45 | 23.5% | 45.2% |
| 2 | parseJSON | node_modules/... | 12.3% | 12.3% |
| 3 | renderTemplate | src/views.js:123 | 8.7% | 15.4% |
...
```

This format is perfect for AI consumption. You can paste it directly into your AI assistant and ask questions like:

* “What are the main performance bottlenecks in this profile?”
    
* “How can I optimize the processRequest function?”
    
* “Is there anything unusual about this CPU usage pattern?”
    
* “Optimize all hot spots.”
    

## **Three Markdown Formats**

We’ve included three output formats optimized for different use cases:

### **Summary (Default)**

The summary format produces a compact hotspots table - ideal for quick AI triage:

```shell
flame run server.js
# or explicitly:
flame run --md-format=summary server.js
```

This is perfect for dropping into an AI chat and asking, “What should I focus on?” or even “Improve the performance of my application”.

### **Detailed**

The detailed format includes full stack traces and comprehensive statistics:

```bash
flame run --md-format=detailed server.js
```

Use this when you need the AI to understand the complete call hierarchy and suggest architectural improvements.

### **Adaptive**

The adaptive format automatically chooses based on profile complexity:

```bash
flame run --md-format=adaptive server.js
```

Simple profiles get the summary treatment; complex profiles get detailed analysis.

## **Works with Both CPU and Heap Profiles**

Flame captures both CPU and heap profiles concurrently, and markdown analysis is generated for both:

```bash
flame run server.js
# Generates:
# cpu-profile-*.pb, cpu-profile-*.html, cpu-profile-*.md
# heap-profile-*.pb, heap-profile-*.html, heap-profile-*.md
```

For heap profiles, the markdown highlights memory allocation hotspots - perfect for asking your AI assistant to help identify memory leaks or excessive allocations.

## **Generate from Existing Profiles**

Already have pprof files? Generate markdown analysis from them:

```bash
# Generate HTML and markdown from existing profile
flame generate cpu-profile.pb

# Use detailed format for comprehensive analysis
flame generate --md-format=detailed cpu-profile.pb
```

## **Programmatic API**

The new generateMarkdown function is also available in the programmatic API:

```javascript
const { generateMarkdown } = require('@platformatic/flame')

// Generate LLM-friendly markdown analysis
await generateMarkdown('profile.pb', 'analysis.md', { format: 'summary' })
```

## **AI Debugging Workflow**

Here’s the workflow we recommend for AI-assisted performance debugging:

1. **Profile your application** during a realistic workload:
    

flame run server.js

1. **Generate traffic** that exercises the slow code paths.
    
2. **Stop profiling** (Ctrl-C) to generate all output files.
    
3. **Open the markdown file** and paste its contents into your AI assistant.
    
4. **Ask**
    
    * “What are the top 3 things I should optimize?”
        
    * “Is this JSON parsing overhead normal?”
        
    * “How can I reduce the time spent in renderTemplate?”
        
    * “Improve the performance of all the hotspots.”
        
5. **Iterate** based on AI changes and re-profile to verify improvements.
    

## **Requirements**

This feature requires Node.js 22.6.0 or later. We’ve bumped the minimum version to take advantage of ES module interoperability improvements needed for the pprof-to-md integration.

Update flame to the latest version:

```shell
npm install -g @platformatic/flame@latest
```

## **LLM Performance Optimization Evals**

We didn’t just build this feature and hope it works - we ran systematic evaluations to measure how well LLMs can identify and fix performance bottlenecks using pprof-to-md output.

The eval process used **Claude Code with Claude Opus 4.5**: an orchestrating agent ran benchmarks, collected profiles, spawned optimization subagents with the markdown analysis, applied suggested fixes, and measured results.

### **Results Summary**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1769082193317/e83d7fa9-8a85-431e-9503-e7400a5e72e1.png align="center")

### **Key metrics:**

* **Correct fix identified:** 5/5 (100%)
    
* **Significant improvement achieved:** 4/5 (80%)
    

### **Highlights**

**json-bottleneck (144x improvement):** The app was parsing a 1MB JSON config file on every request. The profile showed the route handler at 71.1% and readFileSync at 10.7%. Claude immediately identified the issue and moved JSON parsing out of the request handler. Result: 8 req/s → 1,122 req/s.

**n-plus-one (12.8x improvement):** Sequential async calls in a loop - the classic N+1 query pattern. Claude recognized this from code analysis (CPU profiles don’t capture async wait time) and parallelized with Promise.all(). Result: 41 req/s → 526 req/s.

**quadratic-algo (127x latency improvement):** O(n²) deduplication using nested loops. Claude suggested using Set for O(1) lookups. Latency dropped from 4,686ms to 37ms with zero errors.

**memory-churn (84x latency improvement):** Creating 4 intermediate arrays with spread copies. Claude combined all operations into a single loop pass. Latency dropped from 5,239ms to 62ms.

### **What We Learned**

1. **Claude correctly identified all 5 performance issues** by reviewing the analysis and then applying the necessary patches.
    
2. **All fixes were idiomatic and correct** - caching parsed config, pre-compiling regex, parallelizing async operations, single-pass array processing, using Set for O(1) lookups.
    
3. **Latency is often a better success indicator than throughput** for optimization evals.
    
4. **The markdown format provides enough information** for Claude to understand call paths and identify hotspots in the codebase.
    

The one failure (regex-hotpath) wasn’t because Claude suggested the wrong fix - it correctly moved the regex pattern outside the loop. The bottleneck was simply masked by I/O operations in that particular workload.

## **From Profile to Actionable Fix**

The real power of LLM-friendly profiles is turning raw data into specific, prioritized recommendations. In one example, we profiled an application, and the AI identified that URL constructor calls accounted for 14.8% of CPU time, garbage collection overhead accounted for 6.7%, and route matching accounted for another 7.1%. But it didn't stop at identifying hotspots; it provided concrete fixes ranked by impact: replace expensive abstractions with simpler alternatives where possible, pre-compute values in loops instead of recalculating them, initialize resources at startup rather than on-demand, and memoize repeated computations. The estimated result? A 20-25% reduction in CPU time from straightforward changes. This is the workflow we envisioned: profile your app, paste the markdown into your AI assistant, and get back a prioritized list of exactly what to fix and how to fix it.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1769082165121/985b726f-713b-45b4-96cf-71475764a5c9.png align="center")

Specifically, this is about TanStack Start. We notified Tanner immediately - they are on it!

## **Built on pprof-to-md**

The markdown generation is powered by our new [pprof-to-md](https://github.com/platformatic/pprof-to-md) library, which we’ve also open-sourced. If you’re building profiling tools and want to add AI-friendly output, check it out.

## **Get Started**

Update to the latest flame and start profiling:

```bash
npm install -g @platformatic/flame@latest

flame run your-app.js
```

Then paste your markdown analysis into your favorite AI assistant and start asking questions. Performance debugging just got a whole lot easier.

---

Have questions or feedback? Open an issue on [GitHub](https://github.com/platformatic/flame) or contact us on our DM.
