What really is Golang’s context?

Vivek Kaushal
3 min readJun 26, 2022

Google’s guidelines on Go specify that the first argument of a function in GoLang should be Go’s context.Context type. While the usage of context is fairly ubiquitous, I feel that most developers (including me) black-box the context argument in GoLang while starting out with development, and lack clarity about its usage.

What is context?

context is a request-scoped variable that makes it easy to pass along request-specific values, environment, deadlines and cancellation signals as arguments to functions, without relying on parameters.

In GoLang, context is available through the context package. You may have come across context while reading Golang code, eg:

import (
"context"
)
func doSomething (ctx context.Context, param1 string) error {
// this function does something
return nil
}

What does it hold?

context holds information about the request which triggered the current goroutine. This information may comprise of:

  • cancellation signals : cancellation signals about the request, populated by the parent where the goroutine to process the request is spawned and consumed by any function invoked to do the processing.
  • response deadlines : the cutoff of response time for the request, beyond which an error is returned.
  • request-scoped variables :variables shared across the scope of a request’s processing which may be helpful for the underlying functions.

The interface for the context package’s Context type :

type Context interface {
// Done returns a channel that is closed when this Context is canceled
// or times out.
Done() <-chan struct{}

// Err indicates why this context was canceled, after the Done channel
// is closed.
Err() error

// Deadline returns the time when this Context will be canceled, if any.
Deadline() (deadline time.Time, ok bool)

// Value returns the value associated with key or nil if none.
Value(key interface{}) interface{}
}

How is it useful?

In a nutshell, context helps make your code efficient in the following ways:

When the Request is Cancelled

You can leverage the context to check if the request has been cancelled. If yes, we can avoid the computational effort of following through with function execution, and the function can return early. A request may be cancelled for various reasons, including a cancellation from the parent or a concurrent error.

When the Deadline is Too Strict

If the deadline of a context if populated, functions can leverage it to understand if continuing with the execution is a smart idea. For example, suppose a function is responsible for writing to disc, and the operation takes 100ms, and the request is scheduled to timeout in 10ms. In that case, it makes more sense to return with an error early and save the computation resource and disc write bandwidth.

This excellent 2014 blog from Sameer Ajmani explains how context can be used to make your application more efficient.

The Case Against Context

An argument can be made that populating values in context with context.WithValue and reading them in child functions with context.Value(key) skirts the interface exposed by child functions. Though I would weigh in here with my opinion that this is an incorrect usage of context . Be careful with your choice values in context , variables with request-wide-scope should be a strict criterion.

That’s it! I hope you got some clarity into what happens inside context and how powerful it can be when used to it’s full potential. If you’d like to further discuss this, feel free to reach out! :)

--

--

Vivek Kaushal

Product | Hacker | Engineer | Building Enterpret | ex-Samsung, IIIT-H | vivekkaushal.com