Idiomatic Go concurrency - sync primitives, channel semantics, the select statement, and the standard channel patterns (cancellation/done-channel, fan-out/fan-in, pipeline, or-done, context…

Apache-2.0Auto-check passedDevelopment

Install Go Concurrency

skills CLI
$ npx skills add inference-gateway/inference-gateway --skill go-concurrency -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install inference-gateway/inference-gateway go-concurrency --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/inference-gateway/inference-gateway.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/go-concurrency .claude/skills/go-concurrency && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
go-concurrency
GitHub stars
214
Token cost
~2.3k tokens
SKILL.md length
786 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
Apache-2.0

At a glance

Idiomatic Go concurrency - sync primitives, channel semantics, the select statement, and the standard channel patterns (cancellation/done-channel, fan-out/fan-in, pipeline, or-done, context…

  • Reviewing Go that spawns goroutines
  • SKILL.md covers Pick your tool, Channel states, select idioms and Gotchas, plus 2 more sections
  • Calls go
  • Coordinates over channels

What it does

Go Concurrency is an agent skill from inference-gateway/inference-gateway. Idiomatic Go concurrency - sync primitives, channel semantics, the select statement, and the standard channel patterns (cancellation/done-channel, fan-out/fan-in, pipeline, or-done, context, worker-pool). Use when writing or reviewing Go that spawns goroutines, shares state, or coordinates over channels, even if the user never says "concurrency" - e.g. data races, deadlocks, goroutine leaks, sync/context/select usage, or "make this parallel". Distilled from luk4z7/go-concurrency-guide.

Its SKILL.md is about 2.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Async programming. It works with DeepSeek, Model Context Protocol, OpenAI and Kubernetes. The repository describes itself as: An open-source, cloud-native, high-performance gateway unifying multiple LLM providers, from local solutions like Ollama to major cloud providers such as OpenAI, Groq, Cohere… The licence is Apache-2.0.

When your agent uses it

  • Reviewing Go that spawns goroutines
  • Coordinates over channels
  • Even if the user never says concurrency - e.g

Example prompts

  • “concurrency”
  • “make this parallel”
  • “/go-concurrency”

What it can do on your machine

Read from SKILL.md and the folder at commit 49d1f12. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • go

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Go Concurrency loads about 2.3k tokens when it runs. Until then it costs about 126 tokens; SKILL.md has 786 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~126
When it runs · the whole SKILL.md, loaded when a task matches
~2.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from inference-gateway/inference-gateway at commit 49d1f12, republished under its Apache-2.0 licence (© inference-gateway). 786 words, ~2,314 tokens.

Download SKILL.mdSave it as .claude/skills/go-concurrency/SKILL.md (or your agent's skills folder).
name
go-concurrency
description
Idiomatic Go concurrency - sync primitives, channel semantics, the select statement, and the standard channel patterns (cancellation/done-channel, fan-out/fan-in, pipeline, or-done, context, worker-pool). Use when writing or reviewing Go that spawns goroutines, shares state, or coordinates over channels, even if the user never says "concurrency" - e.g. data races, deadlocks, goroutine leaks, sync/context/select usage, or "make this parallel". Distilled from luk4z7/go-concurrency-guide.
license
Apache-2.0

Go Concurrency

A quick-reference for writing and reviewing concurrent Go. Reach for the table that fits the problem, copy the nearest pattern, then check it against the gotchas. Verify everything with go test -race.

Don't communicate by sharing memory; share memory by communicating. Use channels to pass ownership of data, distribute work, and signal. Use a mutex for in-place shared state (caches, counters, registries).

Pick your tool

NeedUse
Hand off / stream values between goroutineschan
Protect shared state in placesync.Mutex / sync.RWMutex (read-heavy)
Wait for N goroutines to finishsync.WaitGroup
Run exactly once (lazy init)sync.Once
Reuse expensive allocations, cut GC pressuresync.Pool
Wake goroutines on a conditionsync.Cond (rare; a channel is usually clearer)
Lock-free counters / flagssync/atomic
Cancellation, deadlines, request-scoped valuescontext.Context

Always defer mu.Unlock() right after mu.Lock() so a panic can't leave the lock held.

Channel states

Behaviour is defined by the operation × the channel's state. Memorize this:

Operationnil channelopen channelclosed channel
receive v := <-cblocks forevera value (or blocks if empty)zero value, ok==false (drains buffer first)
send c <- vblocks foreversends (or blocks if full)panic
close(c)paniccloses itpanic
  • Unbuffered (make(chan T)): send and receive rendezvous - each blocks until the other is ready. This is the synchronization.
  • Buffered (make(chan T, n)): send blocks only when full, receive only when empty. A buffer decouples timing; it does not remove backpressure.
  • Ownership rule: exactly one goroutine owns a channel - it creates, writes, and closes it, then hands consumers a receive-only <-chan T. This makes the panics above structurally impossible. Receivers never close.
  • range c reads until the channel is closed; v, ok := <-c detects closure.

select idioms

select blocks until one case is ready; if several are ready it picks one pseudo-randomly (so no case can starve another). nil channels are never ready - set a channel to nil to disable its case.

go
// timeout - but time.After leaks a timer until it fires; in a hot loop use a
// context or a reused time.Timer instead.
select {
case v := <-c:
    use(v)
case <-time.After(time.Second):
    return errTimeout
}

// non-blocking poll
select {
case v := <-c:
    use(v)
default: // nothing ready, carry on
}

// cancellation - prefer sending under a done/ctx guard so you never block forever
select {
case out <- v:
case <-done:
    return
}

Gotchas

  • Data race: concurrent read+write of the same variable with no synchronization. Undefined behaviour. Catch it with go test -race / go run -race.
  • Goroutine leak: a goroutine blocked on a channel that will never proceed. Every goroutine you start needs a guaranteed exit - a done/ctx signal or a channel that will close. Leaks accumulate silently.
  • Deadlock: all goroutines blocked. Causes: acquiring locks in inconsistent order (always lock in the same order), or send/receive on a nil channel, or an unbuffered send with no receiver. fatal error: all goroutines are asleep.
  • Send on closed channel / double close: panics. Follows from the ownership rule - one owner closes, once.
  • Loop-variable capture: pre-Go 1.22, for _, v := range xs { go f(v) } shared one v; pass it as an argument. Go 1.22+ gives each iteration its own copy. Know which Go you target.
  • Livelock / starvation: goroutines run but make no progress (livelock), or a greedy lock-holder keeps others from ever running (starvation). Usually a sign to add backoff or rebalance critical-section size.
Show full SKILL.md (307 more words)Show less

Signature patterns

Short, copy-ready skeletons. They use any (= interface{}) and assume Go 1.22+ loop semantics.

Done-channel cancellation - pass a read-only done; close it once to stop all listeners. Send results under the done guard so a cancelled consumer can't wedge the producer.

go
func worker(done <-chan struct{}, in <-chan string) <-chan string {
    out := make(chan string)
    go func() {
        defer close(out)
        for s := range in {
            select {
            case out <- transform(s):
            case <-done: // caller cancelled → exit, no leak
                return
            }
        }
    }()
    return out
}

done := make(chan struct{})
defer close(done) // every return path cancels the worker

Fan-out / fan-in - many workers read one input channel (distribute load), one channel merges their results. No value is processed twice.

go
func fanIn(done <-chan struct{}, cs ...<-chan int) <-chan int {
    out := make(chan int)
    var wg sync.WaitGroup
    wg.Add(len(cs))
    for _, c := range cs {
        go func(c <-chan int) {
            defer wg.Done()
            for v := range c {
                select {
                case out <- v:
                case <-done:
                    return
                }
            }
        }(c)
    }
    go func() { wg.Wait(); close(out) }() // close once every worker drains
    return out
}

Pipeline - compose stages, each a goroutine that reads one channel and returns the next. Every stage closes the channel it owns, so closure propagates downstream and range terminates cleanly.

go
func sq(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for n := range in {
            out <- n * n
        }
    }()
    return out
}

for n := range sq(sq(gen(2, 3))) { // 16, 81
    fmt.Println(n)
}

Or-done - range over a channel without leaking when you might quit early. Wrap the channel; the loop body stays clean.

go
func orDone(done, c <-chan any) <-chan any {
    out := make(chan any)
    go func() {
        defer close(out)
        for {
            select {
            case <-done:
                return
            case v, ok := <-c:
                if !ok {
                    return
                }
                select {
                case out <- v:
                case <-done:
                }
            }
        }
    }()
    return out
}

for v := range orDone(done, stream) { // safe; exits on done or closure
    use(v)
}

Context - the standard cancellation/deadline carrier. Take ctx as the first argument, always defer cancel(), and honor ctx.Done() in your loops.

go
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel() // releases resources even on early return

req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
resp, err := http.DefaultClient.Do(req) // aborts on cancel/timeout

select {
case out <- v:
case <-ctx.Done():
    return ctx.Err() // context.Canceled or DeadlineExceeded
}

Queuing / semaphore - a buffered channel bounds how many goroutines run at once. Acquire before launching, release on exit.

go
sem := make(chan struct{}, runtime.NumCPU()) // N concurrent slots
var wg sync.WaitGroup
for _, job := range jobs {
    sem <- struct{}{} // blocks while N are in flight
    wg.Add(1)
    go func(job Job) {
        defer wg.Done()
        defer func() { <-sem }() // free the slot
        process(job)
    }(job)
}
wg.Wait()

Lower-frequency patterns from the source, when you need them: or-channel (combine many done signals into one), tee (duplicate one stream into two), bridge (flatten a channel-of-channels), heartbeat (periodic liveness signal for monitoring), replicated requests (fan a request to N handlers, take the first reply, cancel the rest).

Scheduler, briefly

Go multiplexes goroutines onto OS threads with an M:N work-stealing scheduler: G = goroutine, M = OS thread, P = processor (a run context). GOMAXPROCS (default runtime.NumCPU()) caps how many Ps run Go code at once; an idle P steals goroutines from a busy P's queue. Goroutines are cheap

  • ~2 KB initial stacks that grow on demand and nanosecond-scale switches - so thousands are fine where threads would not be. You rarely manage any of this directly; you make goroutines cancellable and let the runtime schedule them. None of it makes a racy program correct - run -race.

Distilled from luk4z7/go-concurrency-guide, which draws on "Concurrency in Go" (Katherine Cox-Buday) and "The Go Programming Language".

© inference-gateway, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/go-concurrency of inference-gateway/inference-gateway.

Open the folder on GitHubat commit 49d1f12

Compare with similar skills

Go Concurrency next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Go Concurrency compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Go Concurrency this skillinference-gateway/inference-gateway214—~2.3kAutomated safety check: PassApache-2.0
Context Handling in fp-goIBM/fp-go2k—~4.2kAutomated safety check: PassApache-2.0
NGINX Ingress Controller Structurenginx/kubernetes-ingress5.1k—~3.8kAutomated safety check: PassApache-2.0
Dotnet Debuggingnovotnyllc/dotnet-artisan233—~2.1kAutomated safety check: PassMIT
Mesh APImr-tbot/mesh-api180—~1.8kAutomated safety check: PassGPL-3.0
Juror ReviewJuror-AI/juror120—~576Automated safety check: PassMIT

Similar skills

  • Official

    Covers handling Go's context.Context idiomatically in fp-go code: reading and scoping context through operators, timeouts, cancellation and converting ctx-first functions.

    2k GitHub stars~4.2k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • NGINX Ingress Controller Structure

    nginx/kubernetes-ingress

    Maps the NGINX Kubernetes Ingress Controller codebase: repository layout, architectural layers, layer-crossing rules and which files are generated.

    5.1k GitHub stars~3.8k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Dotnet Debugging

    novotnyllc/dotnet-artisan

    Debugs Windows and Linux/macOS applications (native, .NET/CLR, mixed-mode) with WinDbg MCP (crash dumps, !analyze, !syncblk, !dlk, !runaway, !dumpheap, !gcroot, BSOD), dotnet-dump, lldb with SOS…

    233 GitHub stars~2.1k tokensUpdated 2 days ago
    DevelopmentAuto-check passed
  • Mesh API

    mr-tbot/mesh-api

    Interact with a Meshtastic LoRa mesh network through MESH-API — list nodes, read messages, send texts, and check connection status.

    180 GitHub stars~1.8k tokensUpdated 2 mo ago
    AI & LLM EngineeringAuto-check passed
  • Juror Review

    Juror-AI/juror

    Inspect Juror Cloud PR findings and, only after an explicit confirmation, start or rerun a hosted Juror review.

    120 GitHub stars~576 tokensUpdated 3 days ago
    DevelopmentAuto-check passed
  • Unblock Dependabot PR

    kubernetes-sigs/cloud-provider-azure

    Official

    Diagnose and unblock failed Dependabot pull requests in cloud-provider-azure by closing Kubernetes minor-version dependency bumps, classifying CI failures, syncing Go modules, retesting quota-flaked…

    294 GitHub stars~1.5k tokensUpdated yesterday
    DevelopmentAuto-check passed

More from inference-gateway/inference-gateway

  • Go

    inference-gateway/inference-gateway

    Idiomatic Go - package and interface design, error wrapping, table-driven tests, generics, the modern standard library (slices/maps/cmp/errors.Join), current syntax, and logging discipline.

    214 GitHub stars~2.4k tokensUpdated yesterday
    Auto-check passed
  • Go Spec Reviewer

    inference-gateway/inference-gateway

    Review a Go design spec before implementation begins - dispatch a subagent that checks a design doc for completeness, consistency, and idiomatic Go (simplicity, small consumer-defined interfaces…

    214 GitHub stars~1.2k tokensUpdated yesterday
    Auto-check passed

Questions about Go Concurrency

What does Go Concurrency do?

Idiomatic Go concurrency - sync primitives, channel semantics, the select statement, and the standard channel patterns (cancellation/done-channel, fan-out/fan-in, pipeline, or-done, context…. Go Concurrency is an agent skill from inference-gateway/inference-gateway. Idiomatic Go concurrency - sync primitives, channel semantics, the select statement, and the standard channel patterns (cancellation/done-channel, fan-out/fan-in, pipeline, or-done, context, worker-pool).

When should I use Go Concurrency?

Go Concurrency fits situations like: reviewing Go that spawns goroutines; coordinates over channels; even if the user never says concurrency - e.g.

How do I install Go Concurrency in Claude Code?

Run `npx skills add inference-gateway/inference-gateway --skill go-concurrency -a claude-code`. Or copy the skill folder (.agents/skills/go-concurrency in inference-gateway/inference-gateway) into .claude/skills/go-concurrency in your project. Claude Code loads it when a task matches its description.

How do I install Go Concurrency in Codex?

Run `npx skills add inference-gateway/inference-gateway --skill go-concurrency -a codex`. Or copy the skill folder (.agents/skills/go-concurrency in inference-gateway/inference-gateway) into .agents/skills/go-concurrency in your project. Codex loads it when a task matches its description.

Can I use Go Concurrency in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add inference-gateway/inference-gateway --skill go-concurrency -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/go-concurrency, .gemini/skills/go-concurrency, .github/skills/go-concurrency and .opencode/skills/go-concurrency in your project.

What does Go Concurrency need to run?

Going by SKILL.md and its folder, Go Concurrency needs the command-line tools its instructions call (go).

Does Go Concurrency access the network?

SKILL.md names 1 domain. As links in the text: github.com. This is read from the text; nothing was executed.

Is Go Concurrency safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Go Concurrency use?

Go Concurrency is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Go Concurrency use?

About 2.3k tokens (SKILL.md is roughly 9.3k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Go Concurrency?

Skills that share tags, products or a category with Go Concurrency: Context Handling in fp-go (IBM/fp-go, 2k stars), NGINX Ingress Controller Structure (nginx/kubernetes-ingress, 5.1k stars), Dotnet Debugging (novotnyllc/dotnet-artisan, 233 stars) and Mesh API (mr-tbot/mesh-api, 180 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Go Concurrency?

inference-gateway (a GitHub organization) maintains it in inference-gateway/inference-gateway, which has 214 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 8, 2026.

Source: inference-gateway/inference-gateway on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.