Request Mirroring for Shadow Deployments
⚙️ Advanced
·
Updated 1 month ago
Setup
Via the UI
The toggle sits in the route wizard in Step 5 — Reliability (together with Retry and Circuit Breaker).
- Create or edit a route
- In Step 5 enable the Request Mirroring toggle
- Add mirror targets:
- Select a peer from the dropdown
- Enter the port of the mirror service
- Add up to 5 targets (the API rejects more with
routes.mirror_max) - Save
Via the API
# Enable mirroring with 2 targets
curl -X PUT https://gatecontrol.example.com/api/v1/routes/1 \
-H "Authorization: Bearer gc_..." \
-H "Content-Type: application/json" \
-d '{
"mirror_enabled": true,
"mirror_targets": [
{ "peer_id": 2, "port": 8080 },
{ "peer_id": 3, "port": 9090 }
]
}'
Important notes
- Write operations are mirrored. POST, PUT, DELETE — everything is sent to the mirror targets. If the mirror target has a database, real write operations are performed there. Make sure mirror targets are designed for this traffic.
- Mirror targets must be active, enabled peers. Disabled or deleted peers are ignored during the config build.
- The mirror target's response is completely discarded — there is no logging or comparison of mirror responses in GateControl.
- Requests with a body larger than 10 MB are mirrored without body (headers only).
- WebSocket upgrade requests are not mirrored.
- Mirroring is only available for HTTP routes, not for L4 (TCP/UDP).
- Under very high traffic the mirror target can be overloaded. The 100-goroutine limit protects GateControl/Caddy, but not the target.
See also
- concepts/routing.md — Handler order and backend matrix
- features/request-tracing.md — Request trace as an alternative to mirroring