Envoy Proxy: circuit breaking, xDS, and tracing setup

As microservice architectures grow, static proxies fail to handle dynamic service discovery and require manual reloads. We configure Envoy Proxy as a data plane, implement circuit breaking, xDS API, and tracing so your infrastructure adapts to changes without downtime. Our team delivers the project turnkey—from audit to ongoing support—ensuring reliable operation in Kubernetes and Service Mesh.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

We've encountered situations where HAProxy struggled with dynamic service discovery in Kubernetes. Retries with jitter were unavailable, and configuration had to be reloaded manually. That's when we implemented Envoy as the data plane — and gained the flexibility that was missing. Envoy is not just a proxy; it's a full platform for microservice architectures. It supports dynamic upstream discovery via xDS API, built-in request tracing, circuit breaking with outlier detection, and retries with jitter. All configuration updates without restarts. This is why Envoy powers Istio, Consul Connect, and AWS App Mesh. Our engineers bring 5+ years of experience and have completed 30+ DevOps projects, ensuring quality implementation. Request a consultation to discuss Envoy integration for your infrastructure. Project cost is determined individually after an audit.

Static configuration: starting without a control plane

For a simple start without a service mesh, a static config suffices. Here's a minimal setup with retry policy:

# envoy.yaml
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains: ["*"]
              routes:
              - match:
                  prefix: "/api/"
                route:
                  cluster: api_service
                  prefix_rewrite: "/"
                  timeout: 30s
                  retry_policy:
                    retry_on: "5xx,connect-failure"
                    num_retries: 3
                    retry_host_predicate:
                    - name: envoy.retry_host_predicates.previous_hosts
                    host_selection_retry_max_attempts: 3
              - match:
                  prefix: "/"
                route:
                  cluster: app_service
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
  - name: api_service
    connect_timeout: 5s
    type: STRICT_DNS
    lb_policy: LEAST_REQUEST
    load_assignment:
      cluster_name: api_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: api-service
                port_value: 8080
  - name: app_service
    connect_timeout: 5s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: app_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: app-service
                port_value: 3000
        - endpoint:
            address:
              socket_address:
                address: app-service-2
                port_value: 3000
admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901

Run with Docker:

docker run -d \
 -p 10000:10000 \
 -p 9901:9901 \
 -v ./envoy.yaml:/etc/envoy/envoy.yaml \
 envoyproxy/envoy:v1.29-latest \
 -c /etc/envoy/envoy.yaml

Circuit breaking: preventing cascading failures

When a service starts slowing down or failing, clients (other microservices) can accumulate requests in queues, causing a cascade failure. Circuit breakers in Envoy monitor upstream health and stop sending requests to problematic hosts. Configuration example:

clusters:
  - name: payment_service
    connect_timeout: 2s
    circuit_breakers:
      thresholds:
        - priority: DEFAULT
          max_connections: 1000
          max_pending_requests: 500
          max_requests: 1000
          max_retries: 3
          track_remaining: true
    outlier_detection:
      consecutive_5xx: 5
      interval: 10s
      base_ejection_time: 30s
      max_ejection_percent: 50
      consecutive_gateway_failure: 3
      enforcing_consecutive_5xx: 100

Outlier Detection: if a host returns 5 consecutive 5xx errors, it is ejected from the pool for 30 seconds. Envoy then sends a probe request — upon success, the host returns.

How outlier detection improves fault tolerance?

Outlier detection in Envoy monitors not only 5xx but also gateway failures, connection failures, and response time. When thresholds are exceeded, the host is excluded from load balancing for a set time. This prevents cascade failures and reduces MTTR. Compared to HAProxy, where manual scripting is required, Envoy provides a ready-made solution configurable via YAML.

Comparison with alternatives: Envoy vs HAProxy and nginx

Envoy offers 3 times more metrics than nginx, but falls behind HAProxy in raw throughput (~200k req/s per core vs ~300k). However, flexibility and observability make it preferable for complex microservice networks.

Parameter Envoy HAProxy nginx
Dynamic configuration xDS API, no restart Only via Lua scripts Only reload
Circuit breaking Built-in + outlier detection Manual scripting No
Tracing Zipkin, Jaeger, Datadog out of the box No Via modules
Number of metrics 1000+ via admin endpoint 200+ 100+
Throughput (req/s) ~200k per core ~300k per core ~150k per core

Circuit breaking in Envoy works twice as efficiently as a manual solution on HAProxy, and tracing is available immediately without extra modules. For a custom project, contact us.

Envoy as a sidecar in Kubernetes

The classic pattern is Envoy alongside every pod:

# kubernetes deployment (fragment) spec:
containers:
  - name: app
    image: myapp:latest
    ports:
      - containerPort: 8080
  - name: envoy
    image: envoyproxy/envoy:v1.29-latest
    args:
      - "-c"
      - "/etc/envoy/envoy.yaml"
    ports:
      - containerPort: 10000
        name: proxy
      - containerPort: 9901
        name: admin
    volumeMounts:
      - name: envoy-config
        mountPath: /etc/envoy
volumes:
  - name: envoy-config
    configMap:
      name: envoy-config

Without Istio, the sidecar is configured manually. With Istio, Envoy is injected automatically via MutatingWebhookConfiguration, and configuration comes from Istiod via xDS.

How does xDS simplify configuration management?

For production infrastructure with dozens of services, static configuration doesn't scale. xDS API allows a control plane (Consul, Pilot in Istio) to dynamically update configuration without restarts:

# envoy-dynamic.yaml — only bootstrap, rest via xDS


dynamic_resources:
  lds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
        - envoy_grpc:
            cluster_name: xds_cluster
  cds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
        - envoy_grpc:
            cluster_name: xds_cluster

static_resources:
  clusters:
    - name: xds_cluster
      connect_timeout: 5s
      type: STATIC
      load_assignment:
        cluster_name: xds_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: control-plane.example.com
                      port_value: 18000

With xDS, you can change routes, add upstream services, and update policies without restarting. This is especially important for canary deployments and A/B testing.

Our implementation process

We work in stages:

  1. Audit of current architecture (1-2 days).
  2. Design configuration with circuit breaking and tracing.
  3. Implementation on staging with load testing.
  4. Deployment to production with gradual traffic shifting.
  5. Documentation and team training.

The result: a ready Envoy infrastructure (static or xDS-based), integration with Istio, Consul, or another control plane, monitoring and alerting (Prometheus + Grafana, dashboards), an operations runbook, and 2 weeks of post-delivery support. Certified engineers ensure stability and performance.

Timeline

Task Duration
Audit and design 1-2 days
Static config, basic proxy 1 day
Circuit breaking + tracing 1-2 days
xDS with Consul/Pilot, dynamic configuration 2-3 days
Full service mesh + monitoring + documentation 4-7 days

Project budget is calculated individually after an audit. Get a consultation — contact us, and we'll prepare a preliminary estimate.