Skip to content

Chapter 14: Context Package

The context package is essential for managing cancellation, deadlines, and request-scoped values across API boundaries and goroutines. It’s the standard way to control the lifetime of operations in Go.

Context is Go’s answer to a fundamental question: how do you propagate cancellation and deadlines through a call graph? When a user cancels a request, how does that signal reach every goroutine working on that request? Context provides a standard, composable solution.

Introduced in Go 1.7 and now ubiquitous in Go APIs, context forms a tree structure where parent cancellation automatically propagates to children. This cascading cancellation prevents resource leaks and ensures graceful shutdowns.

This chapter covers context creation, cancellation patterns, timeouts, deadlines, and request-scoped values. You’ll learn when to use context, how to propagate it correctly, and common pitfalls to avoid.

When handling requests (HTTP, gRPC, database queries), you often need to:

  • Cancel work when a request is cancelled: User closes browser, don’t waste resources
  • Set timeouts for operations: Prevent operations from running forever
  • Pass request-scoped data: User ID, trace ID, authentication tokens across the call stack

Without context, these are hard problems. Cancellation requires passing done channels everywhere. Timeouts need manual timer management. Request data either goes in globals (bad) or requires threading through every function signature (tedious).

Context solves all three elegantly. It’s passed as the first parameter to functions, carrying cancellation signals, deadlines, and values. The pattern is universal across the Go ecosystem.

context.Background() is the root context, typically used in main, init, or tests:

WithCancel returns a derived context that can be cancelled:

Set automatic cancellation after a duration or at a specific time:

Pass request-scoped values through the context:

Every HTTP request comes with a context:

Always pass context as the first parameter:

  1. Always pass context as the first parameter named ctx
  2. Use WithCancel for manual cancellation of goroutines
  3. Use WithTimeout/WithDeadline for automatic time-based cancellation
  4. Use WithValue sparingly - only for request-scoped data
  5. Always call cancel (usually with defer cancel())
  6. Check ctx.Done() in loops and long operations
  7. Never store context in structs - pass it per-call
  8. Use custom types for keys to avoid collisions

Create a rate-limited API client that respects context cancellation:

Context-Aware API Client

medium

Implement a simple API client that fetches data with rate limiting and respects context cancellation/timeouts.


Chapter in progress
0 / 14 chapters completed

Back to Quick Reference