Search and navigate

Pages

Start HereRoadmapTutorialsCheatsheetInterview QuestionsResources

Published tutorials

Building a REST API with Go: The Complete TutorialGeneric Functions in Go: Writing Reusable CodeGo Benchmarking: Measuring Performance with testing.BGo Channels: Communication Between GoroutinesGo Constraints: comparable, Ordered and Custom SetsGo Context: Cancellation, Deadlines, and Request ValuesGo HTTP Client: Timeouts, JSON, and Reliable RequestsGo HTTP Middleware: Build a Production ChainGo Interview Questions: 25 Answers That Show UnderstandingGo Mutex: Protecting Shared State from Race ConditionsGo net/http: Build an HTTP Server from ScratchGo select Statement: Multiplexing Channels ExplainedGo Tools You Need for a Reliable Development LoopGo Tutorial: From First Program to Backend FoundationsGo Type Parameters: Syntax and Constraints ExplainedGo Worker Pool Pattern: Bounded Concurrency at ScaleGo's Type System Deep Dive: Static Typing Done RightGolang Compilation and Execution ExplainedGolang File Structure for Modules and ApplicationsGolang Hello World and Your First Go ProgramGolang IDEs: Choose an Editor for Your WorkflowGolang Interfaces: What They Are and How to Use ThemGoroutine Leaks in Go: How to Detect and Prevent ThemGoroutines in Go: Concurrency Without LeaksHow to Download and Install Golang SafelyHow to Learn Golang with a Focused Study PlanIntegration Testing in Go: Testing Real BoundariesJSON in Go: Encoding, Decoding, and ValidationLearn Golang with a Practical Beginner CourseMocking in Go: Test Doubles Without Magicsync.WaitGroup in Go: Coordinating Multiple GoroutinesTable-Driven Tests in Go: The Idiomatic WayTesting in Go: Table Tests, HTTP, Fakes, and CoverageWhat Is Go and How Does a Go Program Work?Why Learn Golang and What Is Go Used For?Writing Unit Tests in Go: A Practical Guide
Open full search and filters →

Go Context: Cancellation, Deadlines, and Request Values

Learn Go context with practical cancellation, timeout, HTTP request, and goroutine examples.

Standard-library lessonGo requirement: Go 1.21+How tutorials are checked
Concurrency · Lesson 1Saved in this browser. No account required.

Verification (10 August 2026): Self-contained runnable examples were compile-tested with Go 1.26.5 on Windows/amd64. Multi-file or contextual snippets and intentional compiler-error demonstrations were checked separately in the repository verification matrix.

context.Context carries cancellation signals, deadlines, and request-scoped values across API boundaries. Its most important job is letting work stop when the caller no longer needs it.

Start with cancellation

Create a derived context and always call its cleanup function:

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

go func() {
	select {
	case <-ctx.Done():
		fmt.Println("stopped:", ctx.Err())
	case <-time.After(time.Second):
		fmt.Println("finished")
	}
}()

cancel()

Closing ctx.Done() broadcasts cancellation to every listener. ctx.Err() explains whether cancellation or a deadline caused the stop.

Add a deadline or timeout

ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()

if err := fetch(ctx); err != nil {
	log.Println(err)
}

Pass the context down; do not replace it with context.Background() inside fetch. Each layer may shorten a deadline, but should not silently discard its caller’s cancellation.

Every descendant can observe the same cancellation signal, but each operation must accept the context or watch ctx.Done() to stop.
Context tree where one request deadline or cancel signal propagates to a database query, downstream HTTP request, and worker goroutine

Make blocking work context-aware

func fetch(ctx context.Context) error {
	select {
	case <-time.After(time.Second):
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}

For HTTP clients, use http.NewRequestWithContext. Database APIs such as QueryContext follow the same pattern.

Use values sparingly

Context values are for request-scoped metadata such as a trace or request ID, not configuration or optional function parameters. Use a private key type to prevent collisions.

type requestIDKey struct{}
ctx = context.WithValue(ctx, requestIDKey{}, "req-123")

Accept a context as the first parameter, never store it in a struct unless an API specifically requires it, and never pass nil. These rules keep cancellation ownership visible.

Common mistakes

  • Forgetting cancel, which retains timers and resources longer than necessary.
  • Starting goroutines that never select on ctx.Done().
  • using context values as a general-purpose dependency container.
  • Logging every context.Canceled as a server failure when the client simply disconnected.

Context is most useful when every layer cooperates. A cancellation signal cannot stop code that never checks it.