How to Use context.WithTimeout in Go: Simple Guide
Use
context.WithTimeout in Go to create a context that automatically cancels after a set time duration. It returns a new context and a cancel function, which you should call to release resources. This helps control how long operations run and handle timeouts gracefully.Syntax
The context.WithTimeout function creates a new context that cancels automatically after the specified timeout duration. It returns two values: the new context and a cancel function.
parent: The original context to derive from, usuallycontext.Background()orcontext.TODO().timeout: The duration after which the context will be canceled.ctx: The new context with timeout.cancel: A function to cancel the context manually and free resources.
go
ctx, cancel := context.WithTimeout(parent, timeout) // Use ctx in operations // Call cancel() when done to release resources
Example
This example shows how to use context.WithTimeout to limit a simulated work operation to 2 seconds. If the work takes longer, the context cancels and the program stops waiting.
go
package main import ( "context" "fmt" "time" ) func main() { // Create a context with 2-second timeout ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() // Ensure resources are freed // Simulate work that takes 3 seconds workDone := make(chan bool) go func() { time.Sleep(3 * time.Second) workDone <- true }() select { case <-workDone: fmt.Println("Work completed") case <-ctx.Done(): fmt.Println("Timeout reached:", ctx.Err()) } }
Output
Timeout reached: context deadline exceeded
Common Pitfalls
Common mistakes when using context.WithTimeout include:
- Not calling the
cancel()function, which can cause resource leaks. - Ignoring the context's
Done()channel and not handling cancellation properly. - Setting a timeout too short or too long for the operation.
Always defer the cancel() call right after creating the context to ensure cleanup.
go
package main import ( "context" "fmt" "time" ) func main() { // Wrong: Not calling cancel() ctx, _ := context.WithTimeout(context.Background(), 1*time.Second) // Correct: Call cancel() to free resources ctx2, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() _ = ctx _ = ctx2 fmt.Println("Remember to call cancel() to avoid leaks") }
Output
Remember to call cancel() to avoid leaks
Quick Reference
| Function | Description |
|---|---|
| context.WithTimeout(parent, timeout) | Creates a context that cancels after timeout |
| cancel() | Function to cancel the context and free resources |
| ctx.Done() | Channel closed when context is canceled or times out |
| ctx.Err() | Returns error explaining why context was canceled |
Key Takeaways
Use context.WithTimeout to limit how long operations run in Go.
Always call the cancel function returned by context.WithTimeout to free resources.
Check ctx.Done() to handle cancellations or timeouts gracefully.
Set timeout durations thoughtfully based on expected operation time.
Use context.WithTimeout with context.Background() or other parent contexts.