tezvyn:

Using context.Context across microservice calls in Go

AI-drafted, machine-checkedSource: interviewintermediate
WHAT IT TESTS

request-scoped context propagation.

OUTLINE

context carries cancellation, deadlines, and values; pass ctx as first arg, set one WithTimeout at the edge, attach a request ID via WithValue, thread it through downstream calls so all cancel…

WHAT THIS TESTS Whether you understand context.Context as Go's standard mechanism for cancellation, deadlines, and request-scoped values, and can apply it across a chain of microservice calls.

A GOOD ANSWER COVERS context.Context carries three things through a call tree: a cancellation signal exposed as the Done channel, an optional Deadline, and request-scoped Values. The convention is to pass ctx as the first parameter to every function that does IO or could block. In a microservices flow, the gateway handler receives the inbound request, derives a context with the overall budget using ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second), and defers cancel. It also attaches a correlation identifier with context.WithValue(ctx, requestIDKey, id) so logs and downstream headers can carry it. This single ctx is then passed into each downstream call, http.NewRequestWithContext or a gRPC call with ctx, so the same deadline governs the entire fan-out. If the deadline elapses or the original client disconnects, Done closes and every blocked downstream call returns a cancellation error promptly, freeing resources rather than running to completion.

COMMON WRONG ANSWERS Giving each hop its own fresh full-length timeout, which multiplies the budget instead of sharing one deadline. Storing large or optional data in context.Value, which is meant only for request-scoped metadata like IDs, not function parameters. Ignoring the returned cancel function, leaking the context. Passing context.Background deep in handlers, discarding inbound cancellation.

LIKELY FOLLOW-UPS Why is context.Value discouraged for general parameter passing? How do you propagate the request ID over the wire, via headers re-read into a new context downstream? How does cancellation actually reach an in-flight HTTP call? What is the difference between WithCancel, WithTimeout, and WithDeadline?

ONE CONCRETE EXAMPLE A checkout endpoint calls inventory, then payment, then shipping. ctx, cancel := context.WithTimeout(r.Context(), 800*time.Millisecond); defer cancel; ctx = context.WithValue(ctx, ridKey, rid). Each service call uses this ctx; if inventory and payment together consume the budget, the shipping call sees Done already closed and returns immediately with a deadline-exceeded error, and the shared request ID ties all three call logs together.

Read the original → pkg.go.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.