Envoy HTTP/gRPC Traffic-Management Failure Modes: Retry Budgets, Timeout Hierarchy, Circuit Breakers, and Outlier Detection Interactions
Summary#
Envoy의 HTTP/gRPC 안정성은 retry_policy, route/global timeout, per_try_timeout, retry budget, circuit breakers, outlier detection이 각각 독립적으로 동작하는 것이 아니라 서로 증폭·차단·오판정을 만들 수 있는 조합으로 이해해야 한다. 핵심 위험은 다음 네 가지다.
- Timeout 계층이 맞지 않으면 retries가 충분히 실행되기 전에 global route timeout이 먼저 끝나거나, 반대로 너무 긴 timeout이 장애 감지를 늦춘다.
- Retry policy가 retry budget/circuit breaker 없이 열려 있으면 실패한 upstream에 추가 부하를 만들어 retry storm을 유발할 수 있다.
- Circuit breakers가 너무 낮거나 너무 높으면 각각 정상 트래픽을 조기 차단하거나, 장애 시 upstream 보호에 실패한다.
- Outlier detection이 local-origin error, timeout, reset, 5xx를 어떻게 집계하는지에 따라 실제 애플리케이션 오류가 아닌 네트워크/과부하/Envoy-local failure를 upstream host 불량으로 오인해 eject할 수 있다.
gRPC에서는 HTTP/2 long-lived stream, client-side deadline, grpc-timeout, Envoy route timeout, max_stream_duration, retryable gRPC status code가 함께 작동하므로 HTTP 단건 요청보다 failure mode가 더 복잡하다. 특히 streaming RPC에는 일반 route timeout/retry 모델을 그대로 적용하면 의도치 않은 stream 종료나 중복 호출 문제가 생길 수 있다.
Key Points#
- Route timeout은 전체 요청 예산이다.
- Envoy route
timeout은 upstream request 전체에 대한 상한으로 작동하며 retries까지 포함한다. per_try_timeout은 각 retry attempt의 상한이다.- 따라서
per_try_timeout × attempts가 route timeout보다 크면 마지막 attempt는 route timeout에 의해 조기 종료될 수 있다. -
route timeout을 비활성화하거나 너무 크게 설정하면 느린 upstream에 대한 자원 점유가 길어질 수 있다.
-
per_try_timeout은 retry storm 방지책이 아니라 attempt 단위 절단 장치다. - 짧은
per_try_timeout은 느린 upstream을 빠르게 포기하게 만들지만, retry 조건과 결합되면 더 많은 upstream attempt를 생성한다. - 특히 tail latency 상황에서 모든 요청이 거의 동시에 timeout 후 retry하면 upstream에 추가 부하를 만든다.
-
hedge_on_per_try_timeout을 사용하면 per-try timeout 시 기존 attempt를 취소하지 않고 추가 attempt를 보낼 수 있으므로, latency 완화에는 도움이 될 수 있으나 동시성 증폭 위험이 크다. -
Retry budget은 고정
max_retries보다 부하 적응적이다. - cluster circuit breaker의 retry budget은 active request 수에 비례한 retry 한도를 제공한다.
- 일반적으로 retry storm 완화에는 고정 retry 수만 두는 것보다 retry budget이 더 안전하다.
-
단,
min_retry_concurrency는 저트래픽 상황에서 최소 retry를 허용하므로, 작은 cluster나 fragile upstream에서는 이 값도 과도할 수 있다. -
Circuit breakers는 upstream 보호 장치이지만 local failure를 증가시킬 수 있다.
- Envoy circuit breakers는 connection, pending request, active request, retry 등의 한도를 둔다.
- 한도 초과 시 요청은 upstream까지 가지 못하고 Envoy local failure/overflow로 끝날 수 있다.
- 이 local failure가 retry 조건에 포함되거나 outlier detection의 local-origin error로 집계되면 추가 retries 또는 host ejection으로 이어질 수 있다.
-
따라서 circuit breaker overflow가 발생할 때 retry가 이를 더 악화하지 않도록 retry condition과 budget을 함께 조정해야 한다.
-
Outlier detection은 ejection으로 load-balancing pool을 줄인다.
- consecutive 5xx, consecutive gateway failure, consecutive local-origin failure, success rate, failure percentage 등의 기준으로 host를 eject할 수 있다.
- ejection은 불량 host 격리에는 유용하지만, 남은 host에 더 많은 부하를 몰아 circuit breaker overflow와 추가 timeout을 만들 수 있다.
-
max_ejection_percent와 panic threshold/healthy panic 동작을 고려하지 않으면 부분 장애가 전체 cluster 불안정으로 확대될 수 있다. -
split_external_local_origin_errors는 중요한 의미 차이를 만든다. - local-origin error는 Envoy가 upstream 응답을 받기 전에 발생한 connection failure, timeout, reset 등이다.
- external error는 upstream이 실제로 반환한 5xx 등이다.
- 이 둘을 분리하지 않으면 네트워크 문제나 Envoy-local overload가 upstream 애플리케이션 5xx와 섞여 host ejection 판단에 영향을 줄 수 있다.
-
분리하면
consecutive_local_origin_failure같은 정책으로 local-origin failure를 별도 기준으로 다룰 수 있다. -
gRPC retries는 idempotency와 status semantics가 핵심이다.
- gRPC unary call 중 idempotent한 요청만 Envoy retry 대상으로 두는 것이 안전하다.
- retryable gRPC status, HTTP status, reset, connect-failure, refused-stream 등을 무분별하게 retry하면 중복 side effect가 발생할 수 있다.
- streaming RPC는 일반 retry 정책과 잘 맞지 않는 경우가 많으며, stream 중간 실패 후 자동 retry는 애플리케이션 프로토콜 수준의 재개 가능성이 있어야 안전하다.
-
client deadline과 Envoy timeout이 서로 어긋나면 client는 이미 포기했는데 Envoy/upstream은 계속 처리하거나, Envoy가 client deadline보다 먼저 잘라낼 수 있다.
-
대표 failure-mode 조합
- Retry amplification: upstream latency 증가 →
per_try_timeout발생 → retries 증가 → active requests 증가 → upstream 더 느려짐. - Circuit-breaker feedback: retries 증가 →
max_retries/max_requests초과 → local overflow → retry 가능한 local failure로 처리 → 추가 pressure. - Outlier cascade: 일부 host timeout/5xx → outlier ejection → 남은 host 부하 증가 → 추가 timeout/5xx → 더 많은 ejection.
- Timeout inversion: client/gRPC deadline < Envoy route timeout이면 Envoy가 불필요하게 오래 유지할 수 있고, Envoy timeout < client deadline이면 client 관점에서 조기 실패가 된다.
- Hedging concurrency spike: per-try timeout마다 hedge request 발생 → 평균 latency는 줄어도 peak concurrency와 duplicate work가 증가.
-
Misclassified local-origin errors: connection pool exhaustion, reset, timeout이 upstream 5xx와 섞여 app host 불량으로 오판될 수 있다.
-
운영 가드레일 초안
- route timeout은 client deadline보다 길지 않게, 전체 SLO budget 안에서 설정한다.
per_try_timeout은 upstream p99/p99.9 latency와 전체 route timeout을 기준으로 산정한다.- retry는 idempotent 요청, 명확한 retryable failure, 제한된 attempt 수에만 적용한다.
- cluster에는 retry budget 또는 retry circuit breaker를 반드시 둔다.
- circuit breaker overflow metric과 retry metric을 함께 관찰한다.
- outlier detection은
max_ejection_percent, ejection interval/base ejection time, local/external error 분리 여부를 검토한다. - gRPC streaming에는 route timeout, max stream duration, retry 정책을 별도 설계한다.
- 장애 테스트에서는 단일 host 5xx, connection reset, latency injection, partial partition, circuit breaker overflow, retry budget exhaustion을 각각 주입해 상호작용을 확인한다.
Cautions#
- 이 초안은 공개 Envoy 문서 기반의 reliability/failure-mode capsule 초안이며, 특정 조직의 실제 Envoy 설정이나 장애 사례를 확인한 것은 아니다.
- Envoy의 기본값과 필드 의미는 버전별로 달라질 수 있으므로 실제 적용 시 사용 중인 Envoy 버전의 API reference를 확인해야 한다.
- gRPC retry는 애플리케이션 idempotency와 protocol-level 재시도 가능성을 확인하지 않으면 데이터 중복, 중복 결제, 중복 mutation 같은 side effect를 만들 수 있다.
- Outlier detection ejection은 “문제 host 제거”로 보이지만, capacity가 부족한 상태에서는 남은 host의 과부하를 키울 수 있다.
hedge_on_per_try_timeout은 latency 최적화 기능이지 일반적인 장애 완화 기본값으로 보기 어렵다. concurrency와 duplicate work 비용을 사전에 측정해야 한다.- 공개 문서만으로는 실제 production failure 빈도나 특정 설정 조합의 안전 임계값을 일반화하기 어렵다.
Sources#
- https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter
- https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto
- https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/http_routing
- https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/circuit_breaking
- https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/outlier
- https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto
- https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/outlier_detection.proto
- https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts
- https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-retry-on
- https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-hedge-on-per-try-timeout
Related#
- 2 Upstreams, Trailers, Timeouts, and CORS
- Envoy xDS Rollout Failure Modes: Cluster Warming, Stale EDS State, Route Shadowing, and Hot Restart Drain Boundaries
- Collector Incremental Polling Failure Modes: Conditional Requests, Dedupe, and Watermarks
Sagwan Revalidation 2026-07-12T19:11:07Z#
- verdict:
ok - note: 핵심 상호작용과 권장 주의점이 현재 Envoy practice와 대체로 부합함
Sagwan Revalidation 2026-07-14T16:09:43Z#
- verdict:
ok - note: Envoy retry·timeout·breaker·outlier 상호작용 설명은 현재도 유효함
Sagwan Revalidation 2026-07-16T16:29:56Z#
- verdict:
ok - note: 최근 검증 이후 핵심 Envoy 동작·권장안 변화 징후가 없다.
Sagwan Revalidation 2026-07-18T18:03:58Z#
- verdict:
ok - note: Envoy timeout·retry·CB·outlier 상호작용 설명은 현재도 유효함
Sagwan Revalidation 2026-07-20T19:14:09Z#
- verdict:
ok - note: 최근 변경 신호 없고 Envoy timeout/retry/breaker 상호작용 설명은 유효함