Skip to main content

Overview

Claude Analytics processes data that Claude Code stores locally in your ~/.claude/ directory. This guide explains all the data types, what each metric means, and how data is computed.

Data Structure Types

All TypeScript interfaces are defined in src/lib/types.ts.

DashboardData

The root data structure that contains all your analytics:
interface DashboardData {
  stats: StatsCache | null;        // Aggregated statistics
  sessions: SessionMeta[];          // Per-session metadata
  history: HistoryEntry[];          // Prompt history
  memories: ProjectMemory[];        // Project memory files with content
  account?: AccountInfo;            // Account identifiers (from export)
  exportedAt?: string;              // ISO timestamp of export
}

SessionMeta

Detailed metadata for each coding session from ~/.claude/usage-data/session-meta/*.json:
interface SessionMeta {
  session_id: string;
  project_path: string;                        // Absolute path to project directory
  start_time: string;                          // ISO timestamp
  duration_minutes: number;
  user_message_count: number;
  assistant_message_count: number;
  tool_counts: Record<string, number>;         // e.g. {"Read": 42, "Edit": 15}
  languages: Record<string, number>;           // e.g. {"TypeScript": 200, "CSS": 50}
  git_commits: number;
  git_pushes: number;
  input_tokens: number;
  output_tokens: number;
  first_prompt: string;
  user_interruptions: number;
  tool_errors: number;
  tool_error_categories: Record<string, number>;
  uses_task_agent: boolean;
  uses_mcp: boolean;
  uses_web_search: boolean;
  uses_web_fetch: boolean;
  lines_added: number;
  lines_removed: number;
  files_modified: number;
  message_hours: number[];                     // Hours when messages were sent
  user_message_timestamps: number[];           // Unix timestamps of user messages
}
Sessions with duration_minutes of 0 are filtered out during data loading (src/lib/load-data.ts:41).

StatsCache

Pre-aggregated statistics computed by Claude Code itself in ~/.claude/stats-cache.json:
interface StatsCache {
  totalSessions: number;
  totalMessages: number;
  firstSessionDate: string;                    // ISO date string
  dailyActivity: DailyActivity[];              // Daily message/session/tool counts
  dailyModelTokens: DailyModelTokens[];        // Daily token usage by model
  modelUsage: Record<string, ModelUsage>;       // Per-model token breakdown
  hourCounts: Record<string, number>;           // Sessions per hour (0-23)
  longestSession: {
    sessionId: string;
    duration: number;      // milliseconds
    messageCount: number;
    timestamp: string;
  };
  version?: string;
  lastComputedDate?: string;
}

ModelUsage

Token breakdown for each AI model:
interface ModelUsage {
  inputTokens: number;
  outputTokens: number;
  cacheReadInputTokens: number;
  cacheCreationInputTokens: number;
  webSearchRequests: number;
  costUSD?: number;                // Total cost in USD for this model
  contextWindow?: number;          // Model's context window size
  maxOutputTokens?: number;        // Model's max output token limit
}

HistoryEntry

Each prompt you’ve sent, stored in ~/.claude/history.jsonl:
interface HistoryEntry {
  display: string;                             // The prompt text
  pastedContents: Record<string, unknown>;     // Any pasted content
  timestamp: number;                           // Unix timestamp (ms)
  project: string;                             // Project path
}

ProjectMemory

Memory files that Claude Code maintains for each project:
interface ProjectMemory {
  project: string;                             // Encoded project directory name
  files: { name: string; content: string }[];  // .md files with content (max 5000 chars)
}

Key Metrics Explained

Session Metrics

Duration — Measured in minutes, calculated from the time of first message to last message in a session. Message Count — Separate counts for user messages and assistant responses. Total messages = user + assistant. Tool Calls — Every time Claude uses a tool (Read, Edit, Bash, Glob, Grep, etc.), it’s counted in tool_counts. Code Changes — Tracked via lines_added, lines_removed, and files_modified fields.

Token Metrics

Input Tokens — Tokens sent to the model (your prompts + context). Output Tokens — Tokens generated by the model (Claude’s responses). Cache Read Tokens — Tokens read from Claude’s prompt cache (reduces cost). Cache Creation Tokens — Tokens used to create cache entries (one-time cost per cache).

Cost Calculation

Cost is computed per model based on token usage and pricing tiers. The ModelUsage.costUSD field contains the total cost for that specific model.

Activity Tracking

Daily Activity — Aggregated counts of messages, sessions, and tool calls per day. Hour Distribution — Shows which hours (0-23) you’re most active, stored in hourCounts. Message Timestamps — Exact timestamps of each user message for granular analysis.

How Data is Loaded

From src/lib/load-data.ts, data loading happens in specific functions:

loadStatsCache()

Reads ~/.claude/stats-cache.json:
export function loadStatsCache(): StatsCache | null {
  try {
    const raw = fs.readFileSync(path.join(CLAUDE_DIR, "stats-cache.json"), "utf-8");
    return JSON.parse(raw);
  } catch {
    return null;
  }
}

loadSessionMetas()

Reads all session metadata files from ~/.claude/usage-data/session-meta/*.json:
export function loadSessionMetas(): SessionMeta[] {
  const dir = path.join(CLAUDE_DIR, "usage-data", "session-meta");
  try {
    const files = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
    return files
      .map((f) => {
        try {
          const raw = fs.readFileSync(path.join(dir, f), "utf-8");
          return JSON.parse(raw) as SessionMeta;
        } catch {
          return null;
        }
      })
      .filter((s): s is SessionMeta => s !== null && s.duration_minutes > 0)
      .sort((a, b) => new Date(b.start_time).getTime() - new Date(a.start_time).getTime());
  } catch {
    return [];
  }
}
Sessions are automatically sorted by start_time in descending order (newest first).

loadHistory()

Reads prompts from ~/.claude/history.jsonl (newline-delimited JSON):
export function loadHistory(): HistoryEntry[] {
  try {
    const raw = fs.readFileSync(path.join(CLAUDE_DIR, "history.jsonl"), "utf-8");
    return raw
      .trim()
      .split("\n")
      .map((line) => {
        try {
          return JSON.parse(line) as HistoryEntry;
        } catch {
          return null;
        }
      })
      .filter((e): e is HistoryEntry => e !== null);
  } catch {
    return [];
  }
}

loadProjectMemories()

Reads memory files from ~/.claude/projects/*/memory/*.md:
export function loadProjectMemories(): ProjectMemory[] {
  const dir = path.join(CLAUDE_DIR, "projects");
  try {
    const projects = fs.readdirSync(dir);
    return projects.map((p) => {
      const memDir = path.join(dir, p, "memory");
      let files: { name: string; content: string }[] = [];
      try {
        const mdFiles = fs.readdirSync(memDir).filter((f) => f.endsWith(".md"));
        files = mdFiles.map((f) => ({
          name: f,
          content: fs.readFileSync(path.join(memDir, f), "utf-8").slice(0, 5000),
        }));
      } catch {
        /* no memory dir */
      }
      return { project: p, files };
    }).filter(p => p.files.length > 0);
  } catch {
    return [];
  }
}
Memory file content is truncated to 5000 characters per file to keep export sizes manageable.

Source Files on Disk

PathFormatContainsLoaded By
~/.claude/stats-cache.jsonJSONPre-aggregated statistics computed by Claude CodeloadStatsCache()
~/.claude/usage-data/session-meta/*.jsonJSON (one per session)Detailed session metadataloadSessionMetas()
~/.claude/history.jsonlJSONL (newline-delimited)Every prompt you’ve sentloadHistory()
~/.claude/projects/<id>/memory/*.mdMarkdownProject-specific memory filesloadProjectMemories()
~/.claude/projects/<id>/<session>.jsonlJSONLFull conversation transcriptsAPI route (local mode only)

Daily Activity Structure

interface DailyActivity {
  date: string;           // YYYY-MM-DD format
  messageCount: number;
  sessionCount: number;
  toolCallCount: number;
}
Used by the activity heatmap to show your coding patterns over time.

Daily Model Tokens Structure

interface DailyModelTokens {
  date: string;                          // YYYY-MM-DD format
  tokensByModel: Record<string, number>; // e.g. {"claude-4.5-sonnet": 50000}
}
Powers the daily tokens chart showing token consumption trends.

Next Steps

Project Filtering

Learn how to filter your analytics by project

Privacy & Security

Understand how your data is protected

Build docs developers (and LLMs) love