Learn Envoy Proxy - Advanced Routing & Traffic Shaping
Episode 18 of 23

Learn Envoy Proxy - Advanced Routing & Traffic Shaping

This episode covers advanced routing: weighted clusters for canaries, mirror traffic and shadowing, header-based routing with path rewrites, and fault injection for chaos engineering.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Introduction

Episode 4 gave you basic routing; episode 18 takes routing to traffic engineering. Advanced routing and traffic shaping lets you send a portion of requests to a new version (canary), duplicate traffic for testing (mirroring), route based on headers, and deliberately inject failures. These capabilities answer the question that always comes up in production: how do you test changes with minimal risk.

Weighted Clusters and Canaries

Splitting Traffic by Weight

Weighted clusters split requests across several clusters by percentage:

Canary dengan weighted clusters
virtual_hosts:
  - name: api_vh
    domains:
      - api.example.com
    routes:
      - match:
          prefix: "/v1/orders"
        route:
          weighted_clusters:
            clusters:
              - name: orders_v1
                weight:
                  value: 95
              - name: orders_v2
                weight:
                  value: 5

With weighted_clusters, 95 percent of /v1/orders requests go to orders_v1 and 5 percent to orders_v2. The total weight doesn't have to be 100; Envoy normalizes proportionally. This is the most basic and most widely used canary mechanism.

Shifting Weights Gradually

A common canary strategy: start at 1 percent, observe metrics and logs, then raise to 10, 50, up to 100 percent. Because config can be changed via xDS without restarts, the shift can be done in minutes.

Weighted Clusters with Metadata

Weights can be defined in endpoint metadata so the control plane determines proportions dynamically. For the lab, just change weight and reload the config.

Mirror Traffic and Traffic Shadowing

Duplicating Requests to a New Version

Mirroring sends a copy of a request to another cluster without changing the client's response:

Mirror request ke versi baru
routes:
  - match:
      prefix: "/v1/orders"
    route:
      cluster: orders_v1
      request_mirror_policies:
        - cluster: orders_v2
          runtime_fraction:
            default_value:
              numerator: 10
              denominator: HUNDRED
          trace_sampled: true

The request_mirror_policies block also sends 10 percent of requests to orders_v2. The client still receives the response from orders_v1; orders_v2's result is discarded — only observability sees it. This is how you test a new version with real traffic without risk.

Why Shadowing Is Valuable

Shadowing answers the question "will the new version behave the same?" without routing real users. Compare the shadow response with the real response in telemetry, then decide based on data. trace_sampled: true ensures mirror requests are also recorded in tracing.

Mirroring Limitations

A few things to watch out for:

  • Mirrored requests are sent without blocking the real response, but they still consume resources.
  • Side effects on the shadow backend (for example database writes) must be considered.
  • Use runtime_fraction to change the mirror percentage dynamically.

Header-Based Routing and Path Rewrites

Routing by Header

Routing can be triggered by specific header values:

Header-based routing
routes:
  - match:
      prefix: "/api/"
      headers:
        - name: X-Canary
          string_match:
            exact: "true"
    route:
      cluster: api_canary
  - match:
      prefix: "/api/"
    route:
      cluster: api_stable

The first route catches every request with the header X-Canary: true and sends it to api_canary. Everything else goes to api_stable. This pattern is used for internal testing: QA teams send a special header, and normal traffic is unaffected.

Complex Match Combinations

Matches can combine path, header, and query parameter at the same time to map a very specific traffic subset — for example the prefix /api/, the header X-Tenant: tenant-a, and the query beta=1.

Path Rewrites in Advanced Routing

Combine header-based routing with the rewrites you learned in episode 4:

Rewrite pada route canary
routes:
  - match:
      prefix: "/api/v2"
      headers:
        - name: X-Experimental
          string_match:
            prefix: "1"
    route:
      cluster: experimental_backend
      prefix_rewrite: "/v2/internal"

prefix_rewrite: "/v2/internal" changes the path before reaching the experimental backend. With this combination, one listener can be a gateway for many routing strategies at once.

Fault Injection for Chaos Engineering

Simulating with Precision

The fault injection from episode 10 is now used as a precise chaos engineering tool — combined with routing:

Fault injection untuk cluster canary
routes:
  - match:
      prefix: "/v1/orders"
      headers:
        - name: X-Chaos
          string_match:
            exact: "1"
    route:
      cluster: orders_v1
      typed_per_filter_config:
        envoy.filters.http.fault:
          "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.Fault
          abort:
            http_status: 500
            percentage:
              numerator: 100
              denominator: HUNDRED

The fault configuration makes every request with the header X-Chaos: 1 fail with a 500 status. By triggering this header on a subset of requests, you can test whether retry and circuit breaking work when the new version misbehaves.

Resilience Testing Patterns

The recommended testing sequence:

  1. Send 10 percent of canary traffic to the new version without interference, observe the baseline.
  2. Enable fault injection on a subset of canary requests.
  3. Observe whether retries, timeouts, and circuit breakers respond correctly.
  4. Disable fault injection and evaluate the metrics.

Chaos at Controlled Scale

Never inject faults into all traffic at once. Start with a small fraction and increase gradually. Envoy's fault injection has a runtime_fraction that can be changed dynamically, giving you full control while an experiment runs.

Mengamati efek fault injection
curl -s -o /dev/null -w "%{http_code}\n" \
  -H "Host: api.example.com" -H "X-Chaos: 1" http://localhost:10000/v1/orders
curl -s localhost:9901/stats | grep "upstream_rq_5xx"

A request with X-Chaos: 1 should produce a 500, then the upstream_rq_5xx metric increases. That's a quick way to prove fault injection is active and measurable.

Closing

Episode 18 gave you full control over traffic shape: weighted clusters for canaries, mirroring for shadowing, header-based routing, and fault injection for precise chaos engineering.

Key takeaways:

  • weighted_clusters splits traffic proportionally for canaries.
  • Shift weights gradually from 1 percent up to 100 percent.
  • request_mirror_policies sends request copies without affecting clients.
  • Header-based routing separates internal traffic from normal traffic.
  • Combine path, header, and query matches for precise routing.
  • Fault injection is a chaos tool: start with a small fraction and watch the metrics.

In the next episode, episode 19, we'll discuss Envoy in Kubernetes and service mesh ecosystems — Envoy sidecars in Istio, the difference between running Envoy directly versus as a mesh data plane, and deployment patterns for Kubernetes workloads.

Learn Envoy Proxy - Advanced Routing & Traffic Shaping | Learn Envoy Proxy