Home › Go › Go concurrency Windsurf rules

Go concurrency Windsurf rules

Windsurf rules for safe Go concurrency: goroutine lifetimes, context cancellation, errgroup, channels, and the race detector.

WindsurfGo

How to use

Save this as .windsurf/rules/go-concurrency.md in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.

Note: Review and test before use. Provided as is, without warranty. See Terms.

.windsurf/rules/go-concurrency.mdDownload  
---
trigger: model_decision
description: Apply when Go code uses goroutines, channels, mutexes, worker pools, or background jobs.
---

# Go concurrency

- Every goroutine has an owner and an exit path. Before writing `go func()`, know what stops it (context cancellation, closed channel, or finished work) and who waits for it.
- Use `errgroup.WithContext` for "run N things, fail fast"; `g.SetLimit(n)` for bounded parallelism. Use `sync.WaitGroup` (`wg.Go(...)`) when errors aren't returned.
- Pass `ctx` into goroutines and `select` on `ctx.Done()` in loops and blocking sends.
- Channels: the sender closes, never the receiver. Unbuffered by default; buffer only with a reason (known producer burst). Don't use channels where a mutex is simpler.
- Protect shared state with `sync.Mutex` held for short sections (and never across I/O); `sync/atomic` types (`atomic.Int64`) for counters.
- Don't copy structs containing mutexes; pass pointers.
- Timers: use `time.NewTimer`/`time.After` inside `select` with ctx; stop tickers with `defer t.Stop()`.
- Don't start goroutines in HTTP handlers that outlive the request unless they're handed to a managed background worker.
- Recover panics in long-lived worker goroutines and report them; a panic in any goroutine crashes the program.
- Test concurrent code with `go test -race`, and use `testing/synctest` for code that depends on time.

## Smells to fix
Unbounded `go` in loops over input, `time.Sleep` for synchronization, ignored errors from goroutines, leaked goroutines waiting on channels nobody closes.

More: all Go rules · all Windsurf rules

Related rules

Go backend CLAUDE.md

CLAUDE.md for idiomatic Go HTTP services using the standard library, sqlc and table-driven tests.

Claude Code (CLAUDE.md)Go

Go CLI (Cobra) CLAUDE.md

CLAUDE.md for command-line tools in Go 1.27 with Cobra: commands, flags, output formats, exit codes, and tests.

Claude Code (CLAUDE.md)Go

Go + Gin web API Windsurf rules

Windsurf rules for Go 1.27 REST APIs built with Gin: handlers, binding/validation, middleware, and tests.

WindsurfGo

Go gRPC service rules

Cursor rules for gRPC services in Go with protobuf, buf for codegen and linting, interceptors, and status errors.

CursorGo

Go Copilot path instructions

Path-specific Copilot instructions (.instructions.md) for Go 1.27 code: errors, context, stdlib routing, and tests.

GitHub CopilotGo

Go stdlib HTTP service AGENTS.md

AGENTS.md for Go 1.27 services using only net/http, slog, and database/sql or pgx, with no web framework.

AGENTS.mdGo

Get new rules weekly

One email a week: fresh rule files, agent tips, and what's changing in Cursor, Claude Code and Copilot. Free, unsubscribe anytime.

Opens the Rulestack Newsletter on beehiiv in a new tab. Or subscribe directly on beehiiv.