← Back to Go Course | Chapter 11: Concurrency | Lesson 8 of 8

The context Package

context is like a timer and a stop button you hand to every worker at once, so you can tell them all 'stop now' or youve run out of time' from one place.
Syntax
go
ctx, cancel := context.WithCancel(parent)
defer cancel()

ctx, cancel := context.WithTimeout(parent, duration)

select {
case <-ctx.Done():
    // ctx.Err()
}

Creating a Context with a Timeout

context.WithTimeout creates a context that automatically signals cancellation once the given duration elapses, which is the standard way to bound how long an operation is allowed to run.

Note: Always call the returned cancel function (often via defer) to release the context's resources promptly.

Example: Creating a Context with a Timeout

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"context"
	"fmt"
	"time"
)

// main is where the program starts running
func main() {
	// Short declaration: create ctx, cancel and infer the type
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Millisecond)
	// defer runs this call when the surrounding function returns
	defer cancel()

	select {
	case <-time.After(100 * time.Millisecond):
		fmt.Println("work finished")
	case <-ctx.Done():
		fmt.Println("cancelled:", ctx.Err())
	}
}

Manual Cancellation with WithCancel

context.WithCancel returns a context plus a cancel function that, when called, immediately signals every listener watching ctx.Done(), useful for stopping work in response to some other event, not just a timeout.

Example: Manual Cancellation with WithCancel

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"context"
	"fmt"
)

// main is where the program starts running
func main() {
	// Short declaration: create ctx, cancel and infer the type
	ctx, cancel := context.WithCancel(context.Background())

	// Start this call in a new goroutine (runs concurrently)
	go func() {
		// Print the values followed by a newline
		fmt.Println("cancelling now")
		cancel()
	}()

	<-ctx.Done()
	// Print the values followed by a newline
	fmt.Println("received cancellation:", ctx.Err())
}

Passing Context to Functions

Idiomatic Go functions that might need to be cancelled or time out accept a context.Context as their first parameter, letting callers control cancellation without the function needing its own timeout logic baked in.

Note: By convention, ctx is always the first parameter and is never stored inside a struct.

Example: Passing Context to Functions

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"context"
	"fmt"
	"time"
)

// Define the function doWork
func doWork(ctx context.Context) {
	select {
	case <-time.After(50 * time.Millisecond):
		fmt.Println("work completed")
	case <-ctx.Done():
		fmt.Println("work cancelled:", ctx.Err())
	}
}

// main is where the program starts running
func main() {
	// Short declaration: create ctx, cancel and infer the type
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
	// defer runs this call when the surrounding function returns
	defer cancel()
	doWork(ctx)
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Storing a context inside a struct field instead of passing it explicitly as the first parameter of each function, as Go convention expects.
  2. Forgetting to call the cancel function returned by context.WithCancel/WithTimeout, leaking resources associated with the context.
  3. Ignoring ctx.Done() inside a long-running goroutine, so it never actually stops even after the context is cancelled.
Chapter Summary
  • context.Context carries cancellation signals and deadlines across API boundaries and goroutines.
  • context.WithTimeout and context.WithCancel create a derived context plus a cancel function.
  • A goroutine should select on ctx.Done() to notice cancellation and stop its work promptly.
  • Convention: context.Context is passed explicitly as a function's first parameter, named ctx.
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.