Go-developers quickly get used to the syntax: functions, interfaces, errors. But almost immediately after "Hello, world", something mysterious begins to appear in the code — context.Context. And not just somewhere in the depths of the package, but right in the signature of every second function. Why is it needed and why is it indispensable?
Let's find out.

What is context in Go
context.Context is a special object that is passed along the call chain and controls:
the lifetime of operations,
cancellation of processes,
deadlines,
transfer of metadata (for example, request ID).
Context is like an "invisible backpack" that a function receives with a call and from which you can get useful information.
Where context is most often found
Working with network requests — cancellation by timeout if the response does not arrive for too long.
Queries to the database — to avoid keeping the connection "hanging" indefinitely.
Background flames — graceful shutdown when the service is completed.
Why is it in almost every argument
Go adheres to the principle: explicit is better than implicit. Instead of global variables or hidden signals, functions directly receive context. This makes the code predictable and gives control at the top level — where the request starts.
func fetchUser(ctx context.Context, id int) (User, error) {
row := db.QueryRowContext(ctx, "SELECT name FROM users WHERE id=?", id)
...
}If the request is set ctx with a timeout, then any operation inside will automatically stop after the time has elapsed.

Important work techniques
Creating a context with a timeout:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()Manual cancellation:
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(time.Second)
cancel() // stop the work of everyone who listens to this ctx
}()Transfer of values (carefully!):
ctx = context.WithValue(ctx, "requestID", "abc123")Important: abuse WithValue is not worth it — it is more like "metadata" than full-fledged data.
Typical mistakes and pitfalls
Did not call
cancel()→ resource leak.We put everything in
WithValue→ readability is lost.We do not pass the context further → we deprive the function of the ability to control itself.
The main idea of context is simple: the control should be at the calling code, not at the called code. That's why in Go almost every public function in the standard library package starts with the argument ctx.
Context is not just a buzzword in Go. It is a built-in tool that makes your programs predictable, manageable, and protected from freezes. The sooner you start using it correctly, the less "pain" you will have in the future.
Codica has new top course on Go 🚀
This is a powerful and clear start for those who want to master the language in which fast and reliable services are written. In the course, we explain everything in simple words: from the first steps to serious concepts like goroutines and contexts.
And we also have a cozy Telegram channel, where we share news from the IT world, analyze interesting tasks and communicate with the community. Subscribe to not miss the most important things.
