Request timeouts
Configure request timeouts in ambient mesh via waypoint proxies to prevent latency in upstream services from cascading into failures.
When a client encounters latency in an upstream service, the client can wait indefinitely, becoming unavailable and propagating failure throughout the network. Request timeouts mitigate this problem by severing the connection after a set period, ensuring that calls succeed or fail within a predictable timeframe.
By default, Istio does not apply a timeout to HTTP requests. This means that without configuration, a slow or unresponsive upstream can stall a client indefinitely. When you configure a timeout, be mindful of the tradeoff: a timeout that is too long delays failure detection and lets latency accumulate; a timeout that is too short causes requests to fail unnecessarily while waiting on a service that would have responded in time.
In this guide, you learn how to set up request timeouts in your ambient mesh.
Note
Request timeouts are supported at the edge of a cluster using a gateway, or when a workload is enrolled in the waypoint layer.
Before you begin
-
Label the default namespace to add it to the ambient mesh.
kubectl label ns default istio.io/dataplane-mode=ambient -
Create a waypoint for the default namespace. A waypoint is required because this resiliency feature configures Layer 7 (L7) proxy behavior. For more information on using waypoints, see Configure waypoints.
istioctl waypoint apply -n default --enroll-namespace --wait
Configure request timeouts
-
To test request timeouts, deploy the
httpbinservice and acurlclient.kubectl apply -f https://raw.githubusercontent.com/istio/istio/1.30.0/samples/httpbin/httpbin.yaml kubectl apply -f https://raw.githubusercontent.com/istio/istio/1.30.0/samples/curl/curl.yaml -
Test latency by simulating an endpoint with a 2-second delay. The
httpbinapplication has an/delay/{delay}endpoint that simulates a response delay of the length requested.kubectl exec deploy/curl -- curl httpbin:8000/delay/2In the output, confirm that
Time TotalandTime Spentshow a value of 2 seconds (0:00:02):% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 432 100 432 0 0 214 0 0:00:02 0:00:02 --:--:-- 214 -
Create an HTTPRoute resource to configure calls to
httpbinwith a 500ms timeout.kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin spec: parentRefs: - group: "" kind: Service name: httpbin port: 8000 rules: - backendRefs: - name: httpbin port: 8000 timeouts: request: 500ms EOFNote
The Gateway API also defines an optional
backendRequesttimeout duration. Unlikerequest, which covers the full round trip including retries,backendRequestcaps each individual backend attempt. This is useful when you have retries configured: for example, arequestof2swith abackendRequestof500msallows up to four retry attempts, each with a 500ms budget, bounded by the 2s total. -
Verify the timeout by making another call to
httpbin.kubectl exec deploy/curl -- curl -v httpbin:8000/delay/2In the output, a 504 “Gateway Timeout” response is returned:
* IPv6: (none) * IPv4: 10.96.103.171 * Trying 10.96.103.171:8000... * Established connection to httpbin (10.96.103.171 port 8000) from 10.244.0.37 port 45612 * using HTTP/1.x > GET /delay/2 HTTP/1.1 > Host: httpbin:8000 > User-Agent: curl/8.16.0 > Accept: */* > * Request completely sent off < HTTP/1.1 504 Gateway Timeout < content-length: 24 < content-type: text/plain < date: Tue, 07 Jul 2026 17:42:22 GMT < server: istio-envoy < x-envoy-decorator-operation: httpbin.default.svc.cluster.local:8000/* < * Connection #0 to host httpbin left intact upstream request timeout -
You can also confirm the timeout by using the time command.
time kubectl exec deploy/curl -- curl -v httpbin:8000/delay/2In the output, the total elapsed time is slightly above the 500ms timeout:
kubectl exec deploy/curl -- curl -v httpbin:8000/delay/2 0.08s user 0.04s system 18% cpu 0.650 total
Cleanup
Delete the sample resources.
kubectl delete httproute httpbin
kubectl delete -f https://raw.githubusercontent.com/istio/istio/1.30.0/samples/httpbin/httpbin.yaml
kubectl delete -f https://raw.githubusercontent.com/istio/istio/1.30.0/samples/curl/curl.yamlFAQs
Is it important to first remove existing timeouts from my applications, or can I just overlay mesh timeouts on top of them as they are?
Removing the logic from your applications and maintaining all resilience configuration in the mesh layer is simpler. However, leaving application-level timeouts in place is not harmful. Consider which timeout takes precedence. For example, an application-level timeout of 100ms preempts a 200ms timeout configured through Istio.
What should I set my timeout to?
In Understanding Distributed Systems, Robert Vitillo suggests setting timeouts to the 99.9th percentile latency of a service. If the client is waiting longer than the time it normally takes for 99.9% of requests to respond, sever the connection.
This principle is based on an acceptable false timeout rate of 0.1% of requests, where you accept that 1 in every 1000 requests times out erroneously.
You can use the observability features of ambient mesh to determine this latency number.