go-concurrency
Skill0 starsChanged 5 months agoMITView on GitHub
Idiomatic, leak-free Go concurrency. This skill should be used when a diff or question contains go func, chan, select, sync.WaitGroup/Mutex/Once, atomic, errgroup, context.WithCancel/Timeout/Cause, a retry or backoff loop, a worker pool, per-request cancellation, or a Close on a goroutine-owned resource — goroutine lifetime and leaks, context propagation and cancel causes, work outliving a request, typed atomics, mutex misuse, data races. Pair with go test -race and goleak. Time-dependent tests belong to go-testing (synctest). Go only.
8 other projects use a version of this.
Adopted by
Most recently taken up by
- inference-gateway/skillstheir own version, first seen Nov 5, 2026
- h0rn3t/golang-skillstheir own version, first seen Nov 5, 2026
- Lu1sDV/skillsmdtheir own version, first seen Nov 1, 2026
- hishamkaram/claude-code-routertheir own version, first seen Oct 27, 2026
- AllThingsSmitty/proven-skillstheir own version, first seen Oct 6, 2026
- Dankosik/golang-backend-skillstheir own version, first seen Sep 8, 2026
Other versions8 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 8
- hishamkaram/claude-code-router★ 12same name
- wpank/ai★ 11same name
- h0rn3t/golang-skills★ 7same name
- inference-gateway/skills★ 3same name
- CasLubbers/code-design-skills★ 2same name
- Lu1sDV/skillsmd★ 2same name
- AllThingsSmitty/proven-skills★ 1same name
- Dankosik/golang-backend-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository9 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .claude/CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- go-codingSkill
- go-errorsSkill
- go-idiomsSkill
- go-layoutSkill
- go-lint-setupSkill
- go-testingSkill
The file
We split this skill into the rules it gives an agent
1 rule. 0 are common, 0 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 7 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 61
Testing time/concurrency: use testing/synctest (stable since Go 1.25) — fake clock + deterministic scheduling.
“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
go-concurrency — Go concurrency
Deterministic backstop: go test -race ./..., go vet ./... (catches copylocks, lost cancel),
and go.uber.org/goleak. The race detector is the source of truth — run it before reasoning.
The runtime also reports leaked goroutines itself: the goroutineleak profile (Go 1.27, no build
flag) — pprof.Lookup("goroutineleak"), or /debug/pprof/goroutineleak under net/http/pprof.
It finds goroutines blocked forever on a channel, a select, or a sync lock, WaitGroup or
Cond, with few false positives, but misses a leak whose channel or lock stays reachable from a
global or a running goroutine, and never counts I/O or syscalls. Keep goleak and synctest in
tests; the profile covers production, where they cannot. Collect it infrequently (every few hours —
a leak stays visible once it happens); each collection slows that garbage-collection cycle.
Rules
- Every goroutine needs a known lifetime. Tie it to a
contextor a done signal. A goroutine that can block forever on a channel send/recv after its reader has returned is a leak — the single most common Go concurrency bug. - Prefer
wg.Go(func(){ … })(Go 1.25) overwg.Add(1); go func(){ defer wg.Done() }()— it removes the Add/Done-mismatch footgun. - For groups that can fail, use
golang.org/x/sync/errgroup: the first non-nil error cancels the group's derived context;g.SetLimit(n)bounds concurrency. Don't hand-roll error+WaitGroup plumbing. - Typed atomics (Go 1.19):
atomic.Int64,atomic.Bool,atomic.Pointer[T]— notatomic.AddInt64(&x, …)on a bare int. Typed forms are self-documenting and can't be read non-atomically by accident. - Context discipline: pass
ctx context.Contextas the first parameter; never store it in a struct (containedctx); don't reach forcontext.Background()deep in a call stack — thread the caller's ctx. HTTP/SQL/RPC calls must carry it (noctx), and set a client timeout. - Make cancellation say why.
ctx.Err()only ever reportscontext.CanceledorDeadlineExceeded, which is useless for diagnosis when several budgets nest. Usecontext.WithCancelCause+cancel(err)(Go 1.20) and readcontext.Cause(ctx), orWithTimeoutCause/WithDeadlineCause(1.21) so the expiring layer names itself.errors.Is(err, context.Canceled)keeps working — the cause rides alongside, it doesn't replaceErr(). - Work that must outlive the request:
context.WithoutCancel(ctx)(Go 1.21) drops cancellation but keeps the values (trace, auth, request ID) — reach for it instead ofcontext.Background(), which throws those away. Give the derived context its own timeout, and tie it to a shutdown path; "outlives the request" must not mean "outlives the process silently". context.AfterFunc(ctx, f)(Go 1.21) instead of a goroutine whose only job is toselectonctx.Done()and clean up; the returnedstopunregisters it if the work finished first.- Don't copy
sync.Mutex/sync.WaitGroupby value (go vetcopylocks). Guard shared maps — a concurrent map write panics;-racecatches it. - Channels: close on the send side, never the receive side; a
nilchannel blocks forever (useful for disabling aselectarm, a bug everywhere else). - Prefer synchronous APIs. Return the result; let the caller decide to run it in a goroutine. A function that spawns internally and hands back a channel — or takes a completion callback — imposes its concurrency model on every caller and hides the goroutine's lifetime, which is exactly where leaks come from.
- Cleanup is explicit, never finalized. Release resources in
Close/defer.runtime.AddCleanup(Go 1.24, preferred over the olderruntime.SetFinalizer: multiple cleanups per object, works on interior pointers, no leak on reference cycles) is a backstop for OS/native handles only — a cleanup may never run, so no correctness may depend on it. - Keep secrets out of goroutine labels. On a module at Go 1.27 or later, a crash traceback prints
each goroutine's
runtime/pproflabels, so a label ends up wherever crash output goes. Label with classes (route, job kind, tenant tier), never tokens or personal data;GODEBUG=tracebacklabels=0turns the printing off. - Testing time/concurrency: use
testing/synctest(stable since Go 1.25) — fake clock + deterministic scheduling. Seego-testing.
Sources
- synctest — https://go.dev/blog/synctest; Go 1.25/1.26 release notes — https://go.dev/doc/go1.26
goroutineleakprofile (generally available in Go 1.27; limitations, cost) — https://go.dev/blog/goroutine-leak-profiles, https://pkg.go.dev/runtime/pprof; traceback labels — https://go.dev/doc/go1.27context(Cause,WithoutCancel,AfterFunc,WithTimeoutCause) — https://pkg.go.dev/context;runtime.AddCleanup— https://pkg.go.dev/runtime#AddCleanup- Code Review Comments (Goroutine Lifetimes, Contexts, Synchronous Functions) — https://go.dev/wiki/CodeReviewComments
- Uber Go Style Guide (Concurrency) — https://github.com/uber-go/guide
Decomposition inspired by samber/cc-skills-golang (MIT © 2026 Samuel Berthe); rules grounded in the sources above.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

