Overview
Deadline propagation makes the time limit a first-class part of the request. Every service sees how much time remains and can decide whether the work is still worth doing.
How it works
The edge sets a deadline when the request arrives. Each hop reads it, deducts its own elapsed time, and passes it on.
edge: deadline = now + 800ms
svc A: remaining 760ms -> calls B with timeout 760ms
svc B: remaining 600ms -> calls C with timeout 600ms
svc C: remaining 20ms -> reject, not enough time
In Go the context carries the deadline, and in gRPC the client sends the remaining timeout in a header that servers convert back into a context. When the deadline fires, in-flight calls are cancelled and database queries receive the cancel signal.
Pitfalls
- Any hop that creates a fresh context or fixed timeout silently breaks the chain. Enforce propagation in shared client libraries.
- Absolute timestamps depend on synchronized clocks, so most systems send a relative remaining duration and accept small error.
- Check the deadline before expensive steps and before retries, not only at the start.
- Cancelling mid-operation can leave partial writes, so combine with transactions or idempotent design.
- Queues should drop expired items at dequeue time instead of processing them.
Key takeaways
- Set the deadline once at the edge.
- Propagate remaining time through every hop and queue.
- Reject early when the budget cannot be met.
- Make cancellation safe for in-flight work.
- Emit a metric for requests rejected due to expired deadlines, which shows where time is being lost along the chain.