Back to Apisix

proxy-cache

docs/en/latest/plugins/proxy-cache.md

3.17.029.8 KB
Original Source
<!-- # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --> <head> <link rel="canonical" href="https://docs.api7.ai/hub/proxy-cache" /> </head>

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

Description

The proxy-cache Plugin provides the capability to cache responses based on a cache key. The Plugin supports both disk-based and memory-based caching options to cache for GET, POST, and HEAD requests.

Responses can be conditionally cached based on request HTTP methods, response status codes, request header values, and more.

Attributes

NameTypeRequiredDefaultValid valuesDescription
cache_strategystringFalsedisk["disk","memory"]Caching strategy. Cache on disk or in memory.
cache_zonestringFalsedisk_cache_oneCache zone used with the caching strategy. The value should match one of the cache zones defined in the configuration files and should correspond to the caching strategy. For example, when using the in-memory caching strategy, you should use an in-memory cache zone.
cache_keyarray[string]False["$host", "$request_uri"]Key to use for caching. Support NGINX variables and constant strings in values. Variables should be prefixed with a $ sign.
cache_bypassarray[string]FalseOne or more parameters to parse value from, such that if any of the values is not empty and is not equal to 0, response will not be retrieved from cache. Support NGINX variables and constant strings in values. Variables should be prefixed with a $ sign.
cache_methodarray[string]False["GET", "HEAD"]["GET", "POST", "HEAD"]Request methods of which the response should be cached.
cache_http_statusarray[integer]False[200, 301, 404][200, 599]Response HTTP status codes of which the response should be cached.
hide_cache_headersbooleanFalsefalseIf true, hide Expires and Cache-Control response headers.
cache_controlbooleanFalsefalseIf true, comply with Cache-Control behavior in the HTTP specification. Only valid for in-memory strategy.
no_cachearray[string]FalseOne or more parameters to parse value from, such that if any of the values is not empty and is not equal to 0, response will not be cached. Support NGINX variables and constant strings in values. Variables should be prefixed with a $ sign.
cache_ttlintegerFalse300>=1Cache time to live (TTL) in seconds when caching in memory. To adjust the TTL when caching on disk, update cache_ttl in the configuration files. The TTL value is evaluated in conjunction with the values in the response headers Cache-Control and Expires received from the Upstream service.
consumer_isolationbooleanFalsetrueIf true, partition the cache by authenticated identity. When the request resolves to an APISIX consumer (ctx.consumer_name) or carries a remote user (ctx.var.remote_user), the identity is prepended to the effective cache key so each consumer gets its own cache namespace. Has no effect when cache_key already contains an identity-bearing variable ($consumer_name, $consumer_group_id, $remote_user, or $http_authorization). Set to false if you want different consumers to share cached responses (for example, on routes where the upstream response is identical regardless of who requested it).
cache_set_cookiebooleanFalsefalseIf true, cache responses that include a Set-Cookie header. Off by default because Set-Cookie is per-recipient and not safe for a shared cache to store. Only valid for in-memory strategy — the on-disk strategy never caches responses with Set-Cookie (NGINX's native proxy_cache enforces this and does not honor this flag). Enable this only for routes where the upstream's Set-Cookie is not user-specific (for example, an A/B-testing variant cookie).

The plugin always honors upstream Cache-Control: private, no-store, and no-cache directives — responses carrying any of these are not cached, regardless of the cache_control flag. The cache_control flag governs request-side semantics (client Cache-Control request directives such as max-age and min-fresh) and TTL derivation from max-age / s-maxage; it does not control whether upstream non-cacheability directives are respected.

Both caching strategies honor the upstream Vary response header (RFC 9111 §4.1). Cache entries are partitioned by the request's values for each header listed in Vary, so a response served with Vary: Accept-Encoding will not be served to a request with a different Accept-Encoding. Responses with Vary: * are treated as not reusable and are not cached.

Static Configurations

By default, values such as cache_ttl when caching on disk and cache zones are pre-configured in the default configuration.

To customize these values, add the corresponding configurations to config.yaml. For example:

yaml
apisix:
  proxy_cache:
    cache_ttl: 10s  # default cache TTL used when caching on disk, only if none of the `Expires`
                    # and `Cache-Control` response headers is present, or if APISIX returns
                    # `502 Bad Gateway` or `504 Gateway Timeout` due to unavailable upstreams
    zones:
      - name: disk_cache_one
        memory_size: 50m
        disk_size: 1G
        disk_path: /tmp/disk_cache_one
        cache_levels: 1:2
      # - name: disk_cache_two
      #   memory_size: 50m
      #   disk_size: 1G
      #   disk_path: "/tmp/disk_cache_two"
      #   cache_levels: "1:2"
      - name: memory_cache
        memory_size: 50m

Reload APISIX for changes to take effect.

Examples

The examples below demonstrate how you can configure proxy-cache for different scenarios.

:::note

You can fetch the admin_key from config.yaml and save to an environment variable with the following command:

bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

:::

Cache Data on Disk

On-disk caching strategy offers the advantages of data persistency when system restarts and having larger storage capacity compared to in-memory cache. It is suitable for applications that prioritize durability and can tolerate slightly larger cache access latency.

The following example demonstrates how you can use proxy-cache Plugin on a Route to cache data on disk.

When using the on-disk caching strategy, the cache TTL is determined by value from the response header Expires or Cache-Control. If none of these headers is present or if APISIX returns 502 Bad Gateway or 504 Gateway Timeout due to unavailable Upstreams, the cache TTL defaults to the value configured in the configuration files.

Create a Route with the proxy-cache Plugin to cache data on disk:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "proxy-cache-route",
    "uri": "/anything",
    "plugins": {
      "proxy-cache": {
        "cache_strategy": "disk"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: proxy-cache-service
    routes:
      - name: proxy-cache-route
        uris:
          - /anything
        plugins:
          proxy-cache:
            cache_strategy: disk
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: proxy-cache-plugin-config
spec:
  plugins:
    - name: proxy-cache
      config:
        cache_strategy: disk
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: proxy-cache-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  ingressClassName: apisix
  http:
    - name: proxy-cache-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: proxy-cache
        enable: true
        config:
          cache_strategy: disk
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f proxy-cache-ic.yaml
</TabItem> </Tabs>

Send a request to the Route:

shell
curl -i "http://127.0.0.1:9080/anything"

You should see an HTTP/1.1 200 OK response with the following header, showing the Plugin is successfully enabled:

text
Apisix-Cache-Status: MISS

As there is no cache available before the first response, Apisix-Cache-Status: MISS is shown.

Send the same request again within the cache TTL window. You should see an HTTP/1.1 200 OK response with the following headers, showing the cache is hit:

text
Apisix-Cache-Status: HIT

Wait for the cache to expire after the TTL and send the same request again. You should see an HTTP/1.1 200 OK response with the following headers, showing the cache has expired:

text
Apisix-Cache-Status: EXPIRED

Cache Data in Memory

In-memory caching strategy offers the advantage of low-latency access to the cached data, as retrieving data from RAM is faster than retrieving data from disk storage. It also works well for storing temporary data that does not need to be persisted long-term, allowing for efficient caching of frequently changing data.

The following example demonstrates how you can use proxy-cache Plugin on a Route to cache data in memory.

Create a Route with proxy-cache and configure it to use memory-based caching:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "proxy-cache-route",
    "uri": "/anything",
    "plugins": {
      "proxy-cache": {
        "cache_strategy": "memory",
        "cache_zone": "memory_cache",
        "cache_ttl": 10
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: proxy-cache-service
    routes:
      - name: proxy-cache-route
        uris:
          - /anything
        plugins:
          proxy-cache:
            cache_strategy: memory
            cache_zone: memory_cache
            cache_ttl: 10
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: proxy-cache-plugin-config
spec:
  plugins:
    - name: proxy-cache
      config:
        cache_strategy: memory
        cache_zone: memory_cache
        cache_ttl: 10
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: proxy-cache-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  ingressClassName: apisix
  http:
    - name: proxy-cache-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: proxy-cache
        enable: true
        config:
          cache_strategy: memory
          cache_zone: memory_cache
          cache_ttl: 10
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f proxy-cache-ic.yaml
</TabItem> </Tabs>

cache_strategy: set to memory for in-memory setting.

cache_zone: set to the name of an in-memory cache zone.

cache_ttl: set the time to live for the in-memory cache to 10 seconds.

Send a request to the Route:

shell
curl -i "http://127.0.0.1:9080/anything"

You should see an HTTP/1.1 200 OK response with the following header, showing the Plugin is successfully enabled:

text
Apisix-Cache-Status: MISS

As there is no cache available before the first response, Apisix-Cache-Status: MISS is shown.

Send the same request again within the cache TTL window. You should see an HTTP/1.1 200 OK response with the following headers, showing the cache is hit:

text
Apisix-Cache-Status: HIT

Cache Responses Conditionally

The following example demonstrates how you can configure the proxy-cache Plugin to conditionally cache responses.

Create a Route with the proxy-cache Plugin and configure the no_cache attribute, such that if at least one of the values of the URL parameter no_cache and header no_cache is not empty and is not equal to 0, the response will not be cached:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "proxy-cache-route",
    "uri": "/anything",
    "plugins": {
      "proxy-cache": {
        "no_cache": ["$arg_no_cache", "$http_no_cache"]
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: proxy-cache-service
    routes:
      - name: proxy-cache-route
        uris:
          - /anything
        plugins:
          proxy-cache:
            no_cache:
              - $arg_no_cache
              - $http_no_cache
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: proxy-cache-plugin-config
spec:
  plugins:
    - name: proxy-cache
      config:
        no_cache:
          - $arg_no_cache
          - $http_no_cache
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: proxy-cache-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  ingressClassName: apisix
  http:
    - name: proxy-cache-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: proxy-cache
        enable: true
        config:
          no_cache:
            - $arg_no_cache
            - $http_no_cache
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f proxy-cache-ic.yaml
</TabItem> </Tabs>

no_cache: If at least one of the values of the URL parameter no_cache and header no_cache is not empty and is not equal to 0, the response will not be cached.

Send a few requests to the Route with the URL parameter no_cache value indicating cache bypass:

shell
curl -i "http://127.0.0.1:9080/anything?no_cache=1"

You should receive HTTP/1.1 200 OK responses for all requests and observe the following header every time:

text
Apisix-Cache-Status: EXPIRED

Send a few other requests to the Route with the URL parameter no_cache value being zero:

shell
curl -i "http://127.0.0.1:9080/anything?no_cache=0"

You should receive HTTP/1.1 200 OK responses for all requests and start seeing the cache being hit:

text
Apisix-Cache-Status: HIT

You can also specify the value in the no_cache header as such:

shell
curl -i "http://127.0.0.1:9080/anything" -H "no_cache: 1"

The response should not be cached:

text
Apisix-Cache-Status: EXPIRED

Retrieve Responses from Cache Conditionally

The following example demonstrates how you can configure the proxy-cache Plugin to conditionally retrieve responses from cache.

Create a Route with the proxy-cache Plugin and configure the cache_bypass attribute, such that if at least one of the values of the URL parameter bypass and header bypass is not empty and is not equal to 0, the response will not be retrieved from the cache:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "proxy-cache-route",
    "uri": "/anything",
    "plugins": {
      "proxy-cache": {
        "cache_bypass": ["$arg_bypass", "$http_bypass"]
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: proxy-cache-service
    routes:
      - name: proxy-cache-route
        uris:
          - /anything
        plugins:
          proxy-cache:
            cache_bypass:
              - $arg_bypass
              - $http_bypass
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: proxy-cache-plugin-config
spec:
  plugins:
    - name: proxy-cache
      config:
        cache_bypass:
          - $arg_bypass
          - $http_bypass
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: proxy-cache-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  ingressClassName: apisix
  http:
    - name: proxy-cache-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: proxy-cache
        enable: true
        config:
          cache_bypass:
            - $arg_bypass
            - $http_bypass
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f proxy-cache-ic.yaml
</TabItem> </Tabs>

cache_bypass: If at least one of the values of the URL parameter bypass and header bypass is not empty and is not equal to 0, the response will not be retrieved from the cache.

Send a request to the Route with the URL parameter bypass value indicating cache bypass:

shell
curl -i "http://127.0.0.1:9080/anything?bypass=1"

You should see an HTTP/1.1 200 OK response with the following header:

text
Apisix-Cache-Status: BYPASS

Send another request to the Route with the URL parameter bypass value being zero:

shell
curl -i "http://127.0.0.1:9080/anything?bypass=0"

You should see an HTTP/1.1 200 OK response with the following header:

text
Apisix-Cache-Status: MISS

You can also specify the value in the bypass header as such:

shell
curl -i "http://127.0.0.1:9080/anything" -H "bypass: 1"

The cache should be bypassed:

text
Apisix-Cache-Status: BYPASS

Cache for 502 and 504 Error Response Code

When the Upstream services return server errors in the 500 range, proxy-cache Plugin will cache the responses if and only if the returned status is 502 Bad Gateway or 504 Gateway Timeout.

The following example demonstrates the behavior of proxy-cache Plugin when the Upstream service returns 504 Gateway Timeout.

Create a Route with the proxy-cache Plugin and configure a dummy Upstream service:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "proxy-cache-route",
    "uri": "/timeout",
    "plugins": {
      "proxy-cache": { }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "12.34.56.78": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: proxy-cache-service
    routes:
      - name: proxy-cache-route
        uris:
          - /timeout
        plugins:
          proxy-cache: {}
    upstream:
      type: roundrobin
      nodes:
        - host: 12.34.56.78
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: dummy-upstream
spec:
  type: ExternalName
  externalName: dummy.example.com
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
  namespace: aic
  name: proxy-cache-plugin-config
spec:
  plugins:
    - name: proxy-cache
      config:
        _meta:
          disable: false
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /timeout
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: proxy-cache-plugin-config
      backendRefs:
        - name: dummy-upstream
          port: 80
</TabItem> <TabItem value="apisix-crd">
yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  namespace: aic
  name: dummy-upstream
spec:
  ingressClassName: apisix
  externalNodes:
  - type: Domain
    name: dummy.example.com
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  namespace: aic
  name: proxy-cache-route
spec:
  ingressClassName: apisix
  http:
    - name: proxy-cache-route
      match:
        paths:
          - /timeout
      upstreams:
      - name: dummy-upstream
      plugins:
      - name: proxy-cache
        enable: true
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f proxy-cache-ic.yaml
</TabItem> </Tabs>

Generate a few requests to the Route:

shell
seq 4 | xargs -I{} curl -I "http://127.0.0.1:9080/timeout"

You should see a response similar to the following:

text
HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: MISS

HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: HIT

HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: HIT

HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: HIT

However, if the Upstream services returns 503 Service Temporarily Unavailable, the response will not be cached.