Problem
Calls without timeouts, or with generous defaults, tie up threads and connections while dependencies stall. Slow responses are often worse than failures because they exhaust capacity and propagate latency upstream.
Bound the time spent waiting on remote calls so slow dependencies cannot hold resources indefinitely.
Calls without timeouts, or with generous defaults, tie up threads and connections while dependencies stall. Slow responses are often worse than failures because they exhaust capacity and propagate latency upstream.
Timeouts are the foundation of every other resilience mechanism. Without them, a retry, circuit breaker, or bulkhead has nothing to react to, because a hung call never reports failure.
Each client sets a connect timeout, a read or response timeout, and where supported an overall deadline. Values are chosen near a high percentile of normal latency, such as p99 plus a margin, rather than defaults of tens of seconds. The caller passes a remaining deadline downstream, for example in a header, so each service budgets its own work and abandons it when the budget is gone. Upstream timeouts exceed the sum of downstream timeouts and retries, preventing work from outliving its requester.
# Envoy route timeouts
routes:
- match: { prefix: "/api/orders" }
route:
cluster: orders
timeout: 2s
retry_policy:
retry_on: connect-failure,reset
num_retries: 1
per_try_timeout: 800ms
Teams adopt this approach when any synchronous call to a network dependency; call chains where latency accumulates across tiers. It is a poor fit when long-running batch operations that should use asynchronous patterns instead, or when in-process calls with no waiting on external resources. The central tensions are fail fast vs tolerate slowness; per-hop autonomy vs end-to-end deadlines; false timeouts vs resource exhaustion. The main benefits are that it delivers: frees resources from stuck calls; makes latency behavior predictable; enables fast failure and fallback; supports end-to-end latency objectives. The main costs to budget for are: too short causes false failures and retry load; too long offers little protection; requires ongoing measurement and tuning; aborted calls may leave side effects uncertain. Governance typically looks like this: latency objectives set by service owners; platform provides defaults and propagation. Expect adoption cost to be low: configuration and measurement, and a best fit for any team calling remote services. Critics point out that timeouts chosen by guesswork either fire constantly or never help, and that a timed-out call may still complete remotely, leaving ambiguous state. Treat these concerns as design inputs, and revisit the decision as traffic, team size, and failure history change.