Request timeouts

Change the default route-level timeout of 15 seconds with an HTTPRoute or kgateway TrafficPolicy. To ensure that your apps are available even if they are temporarily unavailable, you can use timeouts alongside Retries.

The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.

Before you begin

  1. Follow the Get started guide to install kgateway.

  2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

  3. Get the external address of the gateway and save it in an environment variable.

    export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
    echo $INGRESS_GW_ADDRESS  
    kubectl port-forward deployment/http -n kgateway-system 8080:8080

Set up timeouts

Specify timeouts for a specific route.

  1. Configure a timeout for a specific route by using the Kubernetes Gateway API-native configuration in an HTTPRoute or by using kgateway’s TrafficPolicy. In the following example, you set a timeout of 20 seconds for httpbin’s /headers path. However, no timeout is set along the /anything path.

    kubectl apply -n httpbin -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin-timeout
    spec:
      hostnames:
      - timeout.example
      parentRefs:
      - group: gateway.networking.k8s.io
        kind: Gateway
        name: http
        namespace: kgateway-system
      rules:
      - matches: 
        - path:
            type: PathPrefix
            value: /headers
        backendRefs:
        - group: ""
          kind: Service
          name: httpbin
          port: 8000
        timeouts:
          request: "20s"
      - matches: 
        - path:
            type: PathPrefix
            value: /anything
        backendRefs:
        - group: ""
          kind: Service
          name: httpbin
          port: 8000
    EOF
    1. Install the experimental channel of the Kubernetes Gateway API to use this feature.

      kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml
    2. Create the HTTPRoute with two routes, /headers and /anything, and add an HTTPRoute rule name to each path. You use the rule name later to apply the timeout to a particular route.

      kubectl apply -n httpbin -f- <<EOF
      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: httpbin-timeout
      spec:
        hostnames:
        - timeout.example
        parentRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: http
          namespace: kgateway-system
        rules:
        - matches: 
          - path:
              type: PathPrefix
              value: /headers
          backendRefs:
          - group: ""
            kind: Service
            name: httpbin
            port: 8000
          name: timeout
        - matches: 
          - path:
              type: PathPrefix
              value: /anything
          backendRefs:
          - group: ""
            kind: Service
            name: httpbin
            port: 8000
          name: no-timeout
      EOF
    3. Create a TrafficPolicy with your timeout settings and use the targetRefs.sectionName to apply the timeout to a specific HTTPRoute rule. In this example, you apply the policy to the timeout rule that points to the /headers path in your HTTPRoute resource.

      kubectl apply -f- <<EOF
      apiVersion: gateway.kgateway.dev/v1alpha1
      kind: TrafficPolicy
      metadata:
        name: timeout
        namespace: httpbin
      spec:
        targetRefs:
        - kind: HTTPRoute
          group: gateway.networking.k8s.io
          name: httpbin-timeout
          sectionName: timeout
        timeouts:
          request: 20s
      EOF

  2. Send a request to the httpbin app along the /headers path that you configured a custom timeout for. Verify that the request succeeds and that you see a X-Envoy-Expected-Rq-Timeout-Ms header with the custom timeout of 20 seconds (20000).

    curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: timeout.example:8080"
    curl -vi localhost:8080/headers -H "host: timeout.example"

    Example output for a successful response:

    {
     "headers": {
       "Accept": [
         "*/*"
       ],
       "Host": [
         "www.example.com:8080"
       ],
       "User-Agent": [
         "curl/7.77.0"
       ],
       "X-Envoy-Expected-Rq-Timeout-Ms": [
         "20000"
       ],
       "X-Forwarded-Proto": [
         "http"
       ],
       "X-Request-Id": [
         "0ae53bc3-2644-44f2-8603-158d2ccf9f78"
       ]
     }
    }
    
  3. Send a request to the httpbin app along the anything path that does not have a custom timeout. Verify that the request succeeds and that you see a X-Envoy-Expected-Rq-Timeout-Ms header with the default timeout of 15 seconds (15000).

    curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: timeout.example:8080"
    curl -vi localhost:8080/anything -H "host: timeout.example"

    Example output for a successful response:

    {
     "headers": {
       "Accept": [
         "*/*"
       ],
       "Host": [
         "www.example.com:8080"
       ],
       "User-Agent": [
         "curl/7.77.0"
       ],
       "X-Envoy-Expected-Rq-Timeout-Ms": [
         "15000"
       ],
       "X-Forwarded-Proto": [
         "http"
       ],
       "X-Request-Id": [
         "0ae53bc3-2644-44f2-8603-158d2ccf9f78"
       ]
     }
    }
    

Cleanup

You can remove the resources that you created in this guide.
kubectl delete httproute httpbin-timeout -n httpbin
kubectl delete TrafficPolicy timeout -n httpbin