Skip to content
Agent Workspaces
Skill

/profile-memory

Profile memory usage in sidecar using Go pprof, system tools, and heap analysis. Covers identifying memory leaks, goroutine leaks, file descriptor accumulation, and CPU profiling. Use when investigating memory issues, profiling performance, debugging memory leaks, or diagnosing

From plugin
sidecar
1.1k19 skills

Claude Code

$ npx -y skills add marcus/sidecar --skill profile-memory --agent claude-code

SKILL.md

profile-memory.SKILL.md
name: profile-memory
description: >
  Profile memory usage in sidecar using Go pprof, system tools, and heap analysis.
  Covers identifying memory leaks, goroutine leaks, file descriptor accumulation,
  and CPU profiling. Use when investigating memory issues, profiling performance,
  debugging memory leaks, or diagnosing unresponsive plugins.
disable-model-invocation: true

Memory Profiling for Sidecar

Quick Triage

| Symptom | Tool | Action | |---------|------|--------| | High RSS / memory growth | vmmap, pprof heap | Check system memory, then heap profile | | Too many open files | lsof | Check FD count and breakdown | | High CPU | pprof cpu, ps | Capture CPU profile | | Goroutine leak | pprof goroutines | Check goroutine count and stacks | | Plugin unresponsive | lsof + goroutines | Check SQLite locks, blocked goroutines |

Triage flow: Is RSS high? -> Check FD count -> Check vmmap -> Check heap profile

System-Level Profiling (No pprof Required)

Find the Process

pgrep -f sidecar
ps aux | grep sidecar

Basic Stats

# RSS, VSZ, CPU%, thread count
ps -o pid,rss,vsz,%cpu,nlwp -p <PID>

# Human-readable RSS
ps -o pid,rss -p <PID> | awk 'NR>1{printf "%d MB\n", $2/1024}'

# Watch over time
while true; do ps -o rss,%cpu -p <PID> | tail -1; sleep 5; done

System Memory

**macOS (vmmap):**

vmmap --summary <PID>

Key sections: VM_ALLOCATE (Go heap), MALLOC (C heap/SQLite), Physical footprint, Swapped.

Red flags:

  • RESIDENT SIZE >500MB for idle sidecar
  • REGION COUNT in thousands for VM_ALLOCATE = mmap leak
  • SWAPPED SIZE growing = memory pressure

**Linux:**

cat /proc/<PID>/status | grep -E 'VmRSS|VmSize|Threads'
pmap -x <PID> | tail -5
ls /proc/<PID>/fd | wc -l

File Descriptor Analysis

# Count and breakdown
lsof -p <PID> | wc -l
lsof -p <PID> | awk '{print $5}' | sort | uniq -c | sort -rn

# Find leaked files
lsof -p <PID> | grep REG | awk '{print $9}' | sort | uniq -c | sort -rn | head -20

# Check session file leaks
lsof -p <PID> | grep -c '\.claude/projects'
lsof -p <PID> | grep -c '\.codex/sessions'

# Watch FD count
while true; do echo "$(date): $(lsof -p <PID> 2>/dev/null | wc -l) FDs"; sleep 30; done

Healthy baselines: Total FDs 50-150, REG files 10-30, PIPEs 10-30, DIRs 5-15.

Red flags: 1000+ total FDs, same file opened 4+ times, growing count over time.

Thread Count

# macOS
ps -M -p <PID> | wc -l
# Linux
ls /proc/<PID>/task | wc -l
# Expected: 20-60 threads. 100+ = goroutine leak likely

Go pprof (Runtime Profiling)

Enable pprof

SIDECAR_PPROF=1 sidecar        # Default port 6060
SIDECAR_PPROF=6061 sidecar     # Custom port

Heap Profile (Current Allocations)

curl http://localhost:6060/debug/pprof/heap > heap.prof
go tool pprof -top heap.prof
go tool pprof heap.prof   # Interactive: top20, list <func>, web

Allocs Profile (All Allocations Since Start)

curl http://localhost:6060/debug/pprof/allocs > allocs.prof
go tool pprof -top allocs.prof

Goroutine Profile

# Count
curl -s http://localhost:6060/debug/pprof/goroutine?debug=1 | head -1

# Full stacks
curl http://localhost:6060/debug/pprof/goroutine?debug=2 > goroutines.txt

# Find stuck goroutines
grep -A5 'runtime.chanrecv' goroutines.txt

Memory Stats

curl http://localhost:6060/debug/pprof/heap?debug=1 | head -30

Compare Snapshots (Best for Finding Leaks)

curl http://localhost:6060/debug/pprof/heap > heap1.prof
# Wait (1 hour or overnight)
curl http://localhost:6060/debug/pprof/heap > heap2.prof
go tool pprof -base heap1.prof heap2.prof
# Then: top20

Continuous Monitoring

./scripts/mem-monitor.sh         # Default: port 6060, 60s interval
./scripts/mem-monitor.sh 6061 30 # Custom port and interval

Output: CSV `time,heap_alloc_bytes,heap_inuse_bytes,goroutines,rss_mb` to `mem-YYYYMMDD-HHMMSS.log`.

CPU Profile

curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof
go tool pprof -top cpu.prof
go tool pprof cpu.prof   # Interactive: top20, list <func>, web

Web UI

go tool pprof -http=:8080 http://localhost:6060/debug/pprof/heap

Requires Graphviz (`brew install graphviz` / `apt install graphviz`) for flame graphs.

What to Look For

**Goroutine leaks:** Count should stabilize at 20-50 after startup. Steady growth = leak. Search for `runtime.chanrecv1`, `runtime.chansend1`, `time.Sleep`.

**Heap growth:** `HeapAlloc` should stabilize after loading sessions. Consistent upward trend = leak.

**Common pprof signatures:** `bufio.Scanner` (buffer not returned), `json.Unmarshal` (large objects retained), `append` in loops (slice growing), channel operations (blocked senders/receivers).

Diagnosing Unresponsive Plugins

1. Check goroutines for blocked operations:

   curl -s http://localhost:6060/debug/pprof/goroutine?debug=2 | grep -A10 'monitor\|td'

2. Check SQLite locks: `lsof -p <PID> | grep '\.db'` 3. Check stuck tea.Cmd goroutines:

   curl -s http://localhost:6060/debug/pprof/goroutine?debug=2 | grep -B2 'fetchData\|FetchData'

4. Check for swap pressure: `vmmap --summary <PID> | grep -E 'Physical|Swapped'`

Common causes: SQLite locked by concurrent td CLI, memory pressure causing swap thrashing, goroutine blocked on unread channel, accumulating fetchData() goroutines.

Known Leak Patterns

File Descriptor Accumulation (Adapter/Watcher Layer)

Files: `internal/adapter/claudecode/watcher.go` etc. Uses fsnotify to watch directories.

Symptoms: RSS grows to 5-15GB overnight, lsof shows 1000+ session files open.

lsof -p <PID> | grep '\.claude/projects' | wc -l
lsof -p <PID> | grep '\.codex/sessions' | wc -l

OutputBuffer Substring Retention

`OutputBuffer.Update()` uses `strings.Split()` creating substrings sharing backing array. NOT a leak if `Update()` keeps being called. Only retains

Read more
@marcus
Ships withsidecar

Always check if you are running in Sidecar: run sidecar agents for capabilities. You might never open your editor again. Status: Ready for daily use. Please report any issues you encounter. Documentation · Getting Started · Comprehensive List of Features

Stars on GitHub

Momentum

stars in total
1.1k
Star history of marcus/sidecar on GitHub, a chart by star-history.com

Other skills on sidecar.

coordinate-agents

coordinate-agents

Drive another Sidecar-managed agent from a shell — discover targets, create the layout, start a provider, prompt and wait, read…

@marcus@marcusInstall Skill
create-adapter

create-adapter

Create conversation adapters for importing AI chat history from different tools (Claude Code, Cursor, Warp, Codex, etc.). Covers…

@marcus@marcusInstall Skill
create-modal

create-modal

Create declarative modals using the modal library API. Covers modal types (confirm, input, select, form), sections (Text,…

@marcus@marcusInstall Skill
create-plugin

create-plugin

Create new sidecar plugins implementing the plugin.Plugin interface, rendering views with Bubble Tea, handling keyboard input via…

@marcus@marcusInstall Skill
create-prompt

create-prompt

Create prompts for sidecar workspaces. Covers prompt structure (name, ticketMode, body), template variables (ticket with…

@marcus@marcusInstall Skill
create-theme

create-theme

Create custom color themes for Sidecar, including base theme selection, color overrides, gradient borders, tab styles,…

@marcus@marcusInstall Skill

More skills from other plugins.

paseo

paseo

Paseo reference for managing hosts, projects, workspaces, workspace scripts, agents, schedules, and heartbeats.

paseo11d23k
@getpaseo@getpaseoInstall Skill
10x
Auto-invoked

10x

Personalized audit that teaches the advanced Paradev (formerly Superset) features the user isn't using yet (automations, parallel…

paradev2d16k
@superset-sh@superset-shInstall Skill
capabilities

capabilities

Your capability catalog — read this at boot. Lists the temporal date-range skills and the external integrations (reached via the…

@chaitanyagiri@chaitanyagiriInstall Skill

Questions about profile-memory.

Which coding agents can use profile-memory?
profile-memory installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.