Problem
Each service in a call chain sets its own timeout independently, so the sum of downstream timeouts can far exceed the client timeout. Work continues long after the user has given up, and slow dependencies hold threads and connections.
Also known as: latency-budget, end-to-end-timeout
Allocate a fixed end-to-end time limit across the hops of a request so the total never exceeds what the caller will wait.
Each service in a call chain sets its own timeout independently, so the sum of downstream timeouts can far exceed the client timeout. Work continues long after the user has given up, and slow dependencies hold threads and connections.
A timeout budget treats time like a shared resource. The edge of the system decides how long the user will wait, and every hop spends from that single allowance instead of choosing a timeout in isolation.
Start with the client limit, subtract local processing, and divide the rest among dependencies using their observed p99 latency. Keep a small reserve for variance.
client budget: 800 ms
gateway work 20 ms
auth service 100 ms (p99 70)
catalog service 300 ms (p99 220)
pricing service 250 ms (p99 180)
reserve 130 ms
Each service computes its outgoing timeout as the minimum of its allocation and the time left on the clock. If a retry would not fit in the time left, it is skipped. Pair this with deadline propagation so downstream services know the remaining time rather than guessing.
None, configuration and libraries
Medium, budgets drift with traffic and code
Low to medium, simple concept
Budgets set from averages rather than tail latencies cause frequent timeouts
Retries ignore the remaining budget and overrun it
Stale budgets after a dependency slows down cause an outage that looks like a client bug