Mert Tosun
← Posts
Context, Timeout, and Cancellation in Go: A Production Reliability Guide

Context, Timeout, and Cancellation in Go: A Production Reliability Guide

Mert TosunGo

A common production failure in Go services is continuing expensive work after the request is already done. Database calls keep running, downstream retries continue, and resource pressure slowly accumulates. context.Context is the mechanism that prevents this by propagating deadlines and cancellation signals across call chains.

Why context matters

context.Context gives you:

  • deadline and timeout boundaries
  • cancellation propagation
  • request-scoped metadata
HTTP request ctx
   -> service ctx
      -> repository ctx
         -> db driver ctx

If one layer ignores context, cancellation stops propagating and reliability suffers.

Timeout budgeting

Do not assign unrelated timeouts blindly. Split budget from ingress to downstream calls.

Example:

  • total request budget: 1200ms
  • DB query budget: 300ms
  • external API budget: 500ms
  • remaining budget for local processing

This prevents hidden tail-latency inflation.

Graceful shutdown pattern

On shutdown signal:

  1. stop accepting new traffic
  2. cancel root context
  3. drain in-flight requests with deadline
  4. close shared resources safely

This avoids partial writes and hanging goroutines during deploy or restart.

Common mistakes

  • using context.Background() in request flow
  • forgetting cancel() in derived contexts
  • swallowing ctx.Err() and retrying forever
  • performing blocking work without deadline

Conclusion

In Go backends, context is not optional plumbing. It is the lifecycle protocol of your service. Correct propagation, timeout budgeting, and cancellation-aware code are the difference between systems that degrade gracefully and systems that fail unpredictably under load.