context Package Best Practices
Team conventions for context keys, timeouts, and shutdown.
Search across all documentation pages
Team conventions for context keys, timeouts, and shutdown.
Apply these rules in code review, onboarding, and service templates so every handler, repository, and RPC client propagates cancellation consistently.
ctx context.Context as the first parameter on blocking APIs. Reviewers reject new I/O without context.ctx, not c or context. Matches Effective Go and staticcheck expectations.Background() mid-request.ctx.Err() when cancel ends work. Preserve with %w only when adding layer context.Query/Exec with *Context variants on request paths. Ban non-context SQL in handlers.r.Context() or framework equivalent. chi/gin/echo wrappers still map to the request.r.WithContext. Values and short timeouts wrap the incoming ctx.context.Canceled without noisy 500s when the response cannot flush. Log at debug for client aborts.http.NewRequestWithContext for outbound HTTP. Tie dependency lifetime to the caller.codes.DeadlineExceeded when appropriate.Background(). Preserves user cancel and upstream clocks.defer cancel() after WithCancel/WithTimeout/WithDeadline. Prevents timer leaks in tests and prod.Shutdown(ctx) with a bounded context on process exit. Pair with signal handling in main.User(ctx)) instead of raw Value calls. Keeps key types private.ctx.Done() in long loops and streams. gRPC Recv/Send loops check each iteration.context.WithoutCancel only for documented post-response work. Billing and audit are common cases.Canceled and DeadlineExceeded paths. Short timeouts beat time.Sleep in CI.-race on packages that spawn goroutines per request. Catches ignored cancel races.Tier A signature and SQL-context rules should fail CI or review bots.
Timeout tables and value ADRs are team policy enforced in review.
Add ctx as first param on exported entry points, keep deprecated wrappers one release, then delete.
Track in a migration issue per package.
Exported blocking helpers yes; pure transforms no.
Document which functions are context-aware in godoc.
Set Transport limits and still pass per-request ctx.
Global Client.Timeout is a backstop, not a replacement for ctx.
Reconcile context cancels on manager shutdown - pass it to client calls.
Do not store on the reconciler struct.
Edge services use stricter outer deadlines; batch workers use longer budgets but still propagate shutdown ctx.
Write differences in the service timeout table.
A shared internal/ctxkeys package works for monorepos.
Libraries published externally should own their keys.
Wrap vendors that lack ctx with timeouts at the boundary.
Open upstream issues when blocking APIs have no context variant.
Context behavior is the same; some drivers may lack cancel.
Verify board targets at build per stack footer note.
Use the group ctx inside goroutines and cancel on first error.
Document errgroup usage in the same concurrency ADR.
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 18, 2026