# PerformanceMonitor Metrics for the Claude Code Analytics Dashboard

> Discover the five essential PerformanceMonitor metrics including CPU, memory, and event types that drive the Claude Code Analytics Dashboard for the davila7/claude-code-templates repository.

- Repository: [Daniel Avila/claude-code-templates](https://github.com/davila7/claude-code-templates)
- Tags: deep-dive
- Published: 2026-04-26

---

**The PerformanceMonitor tracks five key metrics—timestamp, CPU percentage, memory RSS, tool name, and event type (start/end)—logging them to a CSV file that powers the analytics dashboard for the davila7/claude-code-templates repository.**

The PerformanceMonitor hook in the `davila7/claude-code-templates` repository provides lightweight system monitoring for Claude Code tool invocations. This component captures precise performance metrics that feed directly into the analytics dashboard, enabling real-time visibility into resource utilization across tool executions. Understanding these metrics is essential for optimizing Claude Code performance and identifying resource-intensive operations.

## What Metrics Does the PerformanceMonitor Track?

The PerformanceMonitor records five specific data points in a lightweight CSV format defined in [`cli-tool/components/hooks/performance/performance-monitor.json`](https://github.com/davila7/claude-code-templates/blob/main/cli-tool/components/hooks/performance/performance-monitor.json). Each entry represents a snapshot of system state during tool execution.

### Timestamp Capture

**Unix epoch timestamps** with nanosecond precision (`date +%s.%N`) provide high-resolution timing data. This allows the analytics dashboard to calculate exact durations between tool start and end events, measure execution latency, and sequence operations chronologically.

### CPU Utilization Monitoring

**Current CPU percentage** of the Claude Code process is captured using `ps -o %cpu=`. This metric reveals which tools consume the most processing power, helping identify CPU-bound operations that might benefit from optimization or caching strategies.

### Memory Consumption (RSS)

**Resident Set Size (RSS)** in kilobytes is recorded via `ps -o rss=`. This measures the actual physical memory held by the process in RAM, excluding swapped memory. Monitoring RSS helps detect memory leaks and track the memory footprint of individual tools over time.

### Tool Identification

The **Tool Name** field captures the identifier of the specific Claude Code tool being invoked through the `$CLAUDE_TOOL_NAME` environment variable. This enables per-tool performance analysis in the dashboard, allowing developers to compare resource usage across different operations.

### Event Lifecycle Tracking

**Event Type** indicates whether the record represents a `start` event (when a tool begins execution) or an `end` event (when it finishes). These lifecycle markers enable the calculation of execution duration and state transitions in the analytics dashboard.

## How Data Capture Works in performance-monitor.json

The PerformanceMonitor implements a hook-based architecture that writes metrics at two critical interception points. According to the source code in [`cli-tool/components/hooks/performance/performance-monitor.json`](https://github.com/davila7/claude-code-templates/blob/main/cli-tool/components/hooks/performance/performance-monitor.json), the system captures data both immediately before tool execution (`PreToolUse`) and immediately after completion (`PostToolUse`).

This dual-capture approach ensures complete visibility into resource utilization throughout the entire tool lifecycle. The CSV format appends each record as a comma-separated line:

```json
{
  "type": "command",
  "command": "echo \"$(date +%s.%N),$(ps -o %cpu= -p $$),$(ps -o rss= -p $$),$CLAUDE_TOOL_NAME,start\" >> ~/.claude/performance.csv"
}

```

## Log Rotation and Data Management

To maintain dashboard performance and prevent unbounded file growth, the PerformanceMonitor implements automatic log rotation. When the CSV file exceeds **1,000 lines**, the system trims the log to retain only the **most recent 500 rows**.

This sliding window approach ensures the analytics dashboard loads quickly while preserving recent historical context. The bounded dataset is particularly important for real-time dashboard rendering in web interfaces consuming this data.

## Consuming Performance Data for Dashboards

The CSV structure enables straightforward parsing across multiple programming environments. Below are practical implementations for processing PerformanceMonitor data.

### Node.js Data Processing

This example reads the performance CSV and calculates average CPU utilization per tool:

```javascript
import fs from 'fs';
import path from 'path';

// Load the generated CSV
const csvPath = path.resolve(process.env.HOME, '.claude/performance.csv');
const rows = fs.readFileSync(csvPath, 'utf-8')
               .trim()
               .split('\n')
               .map(line => line.split(','));

// Convert to a more friendly structure
const metrics = rows.map(([ts, cpu, mem, tool, phase]) => ({
  timestamp: Number(ts),
  cpuPercent: parseFloat(cpu),
  memoryKB: parseInt(mem, 10),
  toolName: tool,
  phase,
}));

// Example: average CPU per tool
const avgCpu = {};
metrics.forEach(m => {
  if (!avgCpu[m.toolName]) avgCpu[m.toolName] = { total: 0, count: 0 };
  avgCpu[m.toolName].total += m.cpuPercent;
  avgCpu[m.toolName].count += 1;
});
for (const tool in avgCpu) {
  console.log(`${tool}: ${(avgCpu[tool].total / avgCpu[tool].count).toFixed(2)} % CPU`);
}

```

### React Dashboard Visualization

For web-based analytics dashboards, you can parse the CSV and render real-time charts:

```tsx
import { useEffect, useState } from 'react';
import Papa from 'papaparse';

export default function PerformanceChart() {
  const [data, setData] = useState<any[]>([]);

  useEffect(() => {
    fetch('/api/performance.csv')
      .then(r => r.text())
      .then(txt => {
        const parsed = Papa.parse(txt, { header: false });
        const rows = parsed.data.map((r: any) => ({
          time: new Date(Number(r[0]) * 1000),
          cpu: parseFloat(r[1]),
          mem: parseInt(r[2], 10),
          tool: r[3],
          phase: r[4],
        }));
        setData(rows);
      });
  }, []);

  return (
    <ResponsiveContainer width="100%" height={300}>
      <LineChart data={data}>
        <XAxis dataKey="time" tickFormatter={t => t.toLocaleTimeString()} />
        <YAxis yAxisId="left" label={{ value: 'CPU %', angle: -90, position: 'insideLeft' }} />
        <YAxis yAxisId="right" orientation="right" label={{ value: 'Memory KB', angle: 90, position: 'insideRight' }} />
        <Line yAxisId="left" type="monotone" dataKey="cpu" stroke="#ff7300" />
        <Line yAxisId="right" type="monotone" dataKey="mem" stroke="#387908" />
        <Tooltip />
      </LineChart>
    </ResponsiveContainer>
  );
}

```

## Extending the Metrics Pipeline

You can extend the PerformanceMonitor to track additional system metrics by modifying the command in [`performance-monitor.json`](https://github.com/davila7/claude-code-templates/blob/main/performance-monitor.json). For example, adding I/O wait statistics:

```json
{
  "type": "command",
  "command": "echo \"$(date +%s.%N),$(ps -o %cpu= -p $$),$(ps -o rss= -p $$),$(cat /proc/$$/io | grep '^rchar' | awk '{print $2}'),$CLAUDE_TOOL_NAME,start\" >> ~/.claude/performance.csv"
}

```

This extensibility allows the analytics dashboard to monitor custom performance indicators relevant to your specific Claude Code workflows.

## Summary

- The PerformanceMonitor captures **five core metrics**: nanosecond-precision timestamps, CPU percentage, memory RSS (kilobytes), tool name identifiers, and event type (start/end).
- Data is logged to `~/.claude/performance.csv` via hooks defined in [`cli-tool/components/hooks/performance/performance-monitor.json`](https://github.com/davila7/claude-code-templates/blob/main/cli-tool/components/hooks/performance/performance-monitor.json).
- Capture occurs at both **PreToolUse** and **PostToolUse** events to provide complete lifecycle visibility.
- Automatic **log rotation** maintains the last 500 rows when the file exceeds 1,000 lines, ensuring optimal dashboard performance.
- The CSV format enables easy parsing in Node.js, Python, or React dashboards for custom analytics visualization.

## Frequently Asked Questions

### Where does PerformanceMonitor store its metrics?

The PerformanceMonitor writes all metrics to `~/.claude/performance.csv` in the user's home directory. This location provides persistent storage across Claude Code sessions while remaining accessible to external dashboard applications.

### How does the analytics dashboard access PerformanceMonitor data?

The analytics dashboard typically reads the CSV file either directly from the filesystem (for local dashboards) or through an API endpoint that exposes the file contents (for web-based dashboards). The simple CSV structure enables consumption by JavaScript, Python, or any language with CSV parsing capabilities.

### Why does PerformanceMonitor use nanosecond-precision timestamps?

Nanosecond precision (`date +%s.%N`) allows the analytics dashboard to accurately measure sub-millisecond tool execution times and sequence rapid-fire tool invocations correctly. This granularity is essential for profiling fast-running Claude Code tools where second-level precision would obscure performance patterns.

### Can I add custom metrics to the PerformanceMonitor?

Yes, you can extend the metrics by modifying the command strings in [`cli-tool/components/hooks/performance/performance-monitor.json`](https://github.com/davila7/claude-code-templates/blob/main/cli-tool/components/hooks/performance/performance-monitor.json). Simply append additional columns to the CSV format using standard shell commands, then update your dashboard parsing logic to handle the extra fields. The modular hook architecture supports arbitrary metric capture as long as the output follows CSV formatting conventions.