Context

Contents
Background vs TODO
Cancel on demand
Timeouts
Values with care

Background vs TODO

Context carries cancellation and deadlines down the call chain. Background starts an empty context at the top of the program. TODO marks a spot where a real context belongs later, usually while refactoring. Both flow into functions as the first argument by convention.

package main import ( "context" "fmt" ) func fetch(ctx context.Context) string { select { case <-ctx.Done(): return "canceled" default: return "data" } } func main() { fmt.Println(fetch(context.Background())) fmt.Println(fetch(context.TODO())) }

data
data

The Done channel stays open while work may continue, so both calls return data here. Later sections close that channel on purpose. Prefer Background in main and tests, and replace each TODO before the code ships.

Cancel on demand

WithCancel returns a child context plus a cancel function. Calling cancel closes the Done channel for that context and all its children. Workers watch Done and stop early instead of finishing stale work. Always call cancel, usually with defer, to release resources.

package main import ( "context" "fmt" ) func main() { ctx, cancel := context.WithCancel(context.Background()) cancel() <-ctx.Done() fmt.Println(ctx.Err()) }

context canceled

Waiting on Done blocks until cancel runs, so this order always prints the same line. Err explains why the context ended, which helps logging. Real programs cancel from timeouts, user actions, or shutdown hooks.

Timeouts

WithTimeout adds a deadline that cancels the context automatically. Slow work loses the race and reports a deadline error. The pattern below is the standard way to bound any call. Timeouts from the client lesson pair well with this tool.

package main import ( "context" "fmt" "time" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) defer cancel() select { case <-time.After(200 * time.Millisecond): fmt.Println("finished") case <-ctx.Done(): fmt.Println(ctx.Err()) } }

context deadline exceeded

The work needs 200 milliseconds but the context allows only 50, so the timeout wins. defer cancel frees the timer even on the fast path. WithDeadline is the sibling for an exact clock time instead of a duration.

Values with care

Context can also carry request-scoped values like IDs and tokens. Use an unexported key type so other packages cannot collide with your keys. Values are for transit data only, never for function options. When in doubt, pass an explicit argument instead.

package main import ( "context" "fmt" ) type userKey struct{} func main() { ctx := context.WithValue(context.Background(), userKey{}, "ada") fmt.Println(ctx.Value(userKey{})) }

ada

Next: Goroutines

Article author: Arthur Isaev

Related articles
Golang
Go course: zero to hero in 50 lessons
What is Go and where it runs
Install Go and check the version
Your first Go program
Modules with go mod
Variables
Constants
Types
Numbers
Strings
Conditions with if
Switch in Go
Loops with for
Arrays in Go
Slices in Go
Maps in Go
Functions in Go
Errors as values
Pointers in Go
Structs in Go
Methods in Go
Interfaces in Go
Embedding instead of inheritance
Generics in Go
Packages and imports
The go toolchain
Testing with go test
Advanced errors
defer in Go
Strings, bytes and runes
Time in Go
JSON
Files and IO
HTTP servers
HTTP clients
Context
Goroutines
Channels
select and sync
CLI: args, flags, env
Logging
Regular expressions
Sorting
Concurrency patterns
Databases with database/sql
Benchmarks and profiling
Toolchain and CI
Project layout
Capstone: wordfreq CLI
Capstone: JSON API server
Hero roadmap: the whole course on one page
Install Go on Windows 11
Install Go on Ubuntu
Install Go on Rocky Linux
Install Go on macOS
Install Go on FreeBSD
Go in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.ru
Write to info@urn.su if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: