Docs
Plugin HubOverview

proxy-mirror

The proxy-mirror plugin copies incoming requests to a secondary upstream while the gateway sends the original requests to their configured upstream. It can mirror every request or sample a portion of traffic for troubleshooting, security inspection, testing, and analytics. The gateway ignores responses from the mirror upstream.

Examples

Mirroring requires a secondary upstream that the gateway can reach. The following examples use NGINX as that upstream and then configure the timeouts that govern mirrored requests.

Mirror Partial Traffic

The following example mirrors approximately 50% of the requests to a secondary NGINX service while all requests continue to the route's original upstream.

Start a sample NGINX server for receiving mirrored traffic:

Set GATEWAY_CONTAINER to the name of the running APISIX or API7 Gateway container. Create a dedicated network and connect the gateway to it:

export GATEWAY_CONTAINER=replace-with-gateway-container-name

docker network create gateway-mirror-net
docker network connect gateway-mirror-net "$GATEWAY_CONTAINER"

Start NGINX on the same network:

docker run -d --name mirror-receiver \
  --network gateway-mirror-net \
  -p 127.0.0.1:8081:80 \
  nginx:1.30.5-alpine

Wait for NGINX to become available:

until curl -fsS "http://127.0.0.1:8081" > /dev/null; do
  sleep 1
done

Set the mirror receiver URL used by the Admin API and ADC examples:

export MIRROR_RECEIVER_URL=http://mirror-receiver

Create a route with proxy-mirror:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d @- <<EOF
  {
    "id": "traffic-mirror-route",
    "uri": "/get",
    "plugins": {
      "proxy-mirror": {
        "host": "$MIRROR_RECEIVER_URL",
        "sample_ratio": 0.5
      }
    },
    "upstream": {
      "nodes": {
        "httpbin.org": 1
      },
      "type": "roundrobin"
    }
  }
EOF

❶ host: configure the scheme and address of the upstream that receives mirrored requests.

❷ sample_ratio: configure the sampling ratio to 0.5 to mirror 50% of the traffic.

Send 20 requests to the route:

for i in $(seq 1 20); do
  curl -fsS "http://127.0.0.1:9080/get" > /dev/null || exit 1
done

All 20 requests to the original upstream should succeed. The command exits early if any request returns an error.

Inspect the NGINX access logs:

docker logs mirror-receiver 2>&1 | grep '"GET /get HTTP/1.1" 404'

The logs should contain approximately 10 requests. The exact number varies because each request is sampled independently. NGINX returns 404 for mirrored requests because its default configuration does not define /get; this response is ignored and does not affect the response from the original upstream.

Configure Mirroring Timeouts

The following example updates the connect, read, and send timeouts used for mirrored requests. Shorter timeouts bound how long requests to the mirror upstream hold connections and consume gateway resources when that upstream is slow or unavailable.

The default connect, read, and send timeouts are 60 seconds. Configure the gateway static settings to change them:

Add or update this section in the gateway configuration file:

config.yaml
plugin_attr:
  proxy-mirror:
    timeout:
      connect: 2000ms
      read: 2000ms
      send: 2000ms

Reload the gateway for changes to take effect.