Goroutine Profile Analysis
Step 1 — Obtain the Profile
Ask the user for the absolute path to a goroutine profile. They may have:
- A
.pb.gzfile (machine-parseable, used withgo tool pprof) - A
debug=2text dump (human-readable, shows goroutine IDs, ages, and states — better for leak detection) - Both (preferred)
If they don't have either, run the golang-pprof-collect skill with profile type goroutine to collect them first. That skill will produce both the .pb.gz and debug=2 dump. Return here with the file path(s).
Step 2 — Extract Profile Data
If pb.gz is available:
Top goroutine stacks by count:
// turbo
go tool pprof -top <profile_path>
Top by cumulative (shows which entry points spawn the most goroutines):
// turbo
go tool pprof -top -cum <profile_path>
Text call graph:
// turbo
go tool pprof -text <profile_path>
If debug=2 text dump is available:
Read the file directly. Parse:
- Total goroutine count (first line:
goroutine profile: total NNNN) - Group goroutines by stack signature
- Note goroutine ages (
N minutesin the header line)
Step 3 — Analyze and Report
Produce a structured analysis with these sections:
Summary
- Total goroutine count
- Breakdown by state: running, runnable, IO wait, chan receive, chan send, select, semacquire, sleep
Goroutine Groups (by stack)
Table: count, state, top stack frames (3-4 lines), likely purpose
Sort by count descending. Group identical stacks.
Leak Indicators
Flag goroutine groups that suggest leaks:
- High count + chan receive/select: Goroutines stuck waiting on channels that may never be signaled
- High count + IO wait on same address: Connection pool exhaustion or stuck HTTP requests
- Long-lived goroutines (debug=2 shows age): Goroutines running for hours/days that aren't expected to be long-lived
- Growing count between snapshots: If user provides two dumps, diff the counts
Blocking / Contention Hotspots
- Goroutines in
semacquire/lock— contention on mutexes - Goroutines in
runtime.goparkviasync.(*Cond).Wait— condition variable waits - Goroutines in
runtime.netpollblock— network IO stalls
Actionable Findings
For each concerning group:
- Identify the code path responsible
- Suggest whether it's expected (e.g., watch goroutines, worker pools) or a leak
- Recommend fixes (context cancellation, bounded worker pools, timeouts)
Follow-up Commands
- Suggest collecting a second snapshot after N minutes and diffing to confirm growth
- Mutex profile:
curl -sK -o mutex.pb.gz "<endpoint>/debug/pprof/mutex"if contention is suspected - Block profile:
curl -sK -o block.pb.gz "<endpoint>/debug/pprof/block"if blocking is suspected
Source: rumstead/golang-pprof-skills — distributed by TomeVault.