Date: Mon, 23 Mar 2026 18:27:10 -0700
Subject: [PATCH 10/11] Addressing the review comments
---
networking/v1alpha3/destination_rule.pb.go | 3 +--
networking/v1alpha3/destination_rule.pb.html | 3 +--
networking/v1alpha3/destination_rule.proto | 3 +--
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/networking/v1alpha3/destination_rule.pb.go b/networking/v1alpha3/destination_rule.pb.go
index 2ad231cab3..5a32e1ae11 100644
--- a/networking/v1alpha3/destination_rule.pb.go
+++ b/networking/v1alpha3/destination_rule.pb.go
@@ -558,8 +558,7 @@ type TrafficPolicy struct {
// Specifies a limit on concurrent retries in relation to the number of active requests.
RetryBudget *TrafficPolicy_RetryBudget `protobuf:"bytes,8,opt,name=retry_budget,json=retryBudget,proto3" json:"retry_budget,omitempty"`
// Adaptive concurrency settings for dynamically adjusting the allowed number of
- // outstanding requests based on sampled latencies. This enables the Envoy
- // adaptive concurrency filter for the destination.
+ // outstanding requests based on sampled latencies.
//
// Note: This operates independently from circuit breaker thresholds (e.g.
// max_connections). Both mechanisms can reject requests, but they act at
diff --git a/networking/v1alpha3/destination_rule.pb.html b/networking/v1alpha3/destination_rule.pb.html
index e6c6e86c87..eb869639f4 100644
--- a/networking/v1alpha3/destination_rule.pb.html
+++ b/networking/v1alpha3/destination_rule.pb.html
@@ -284,8 +284,7 @@ TrafficPolicy
Adaptive concurrency settings for dynamically adjusting the allowed number of
-outstanding requests based on sampled latencies. This enables the Envoy
-adaptive concurrency filter for the destination.
+outstanding requests based on sampled latencies.
Note: This operates independently from circuit breaker thresholds (e.g.
max_connections). Both mechanisms can reject requests, but they act at
different layers: adaptive concurrency limits outstanding requests at
diff --git a/networking/v1alpha3/destination_rule.proto b/networking/v1alpha3/destination_rule.proto
index eade9d94e0..285433060f 100644
--- a/networking/v1alpha3/destination_rule.proto
+++ b/networking/v1alpha3/destination_rule.proto
@@ -309,8 +309,7 @@ message TrafficPolicy {
RetryBudget retry_budget = 8;
// Adaptive concurrency settings for dynamically adjusting the allowed number of
- // outstanding requests based on sampled latencies. This enables the Envoy
- // adaptive concurrency filter for the destination.
+ // outstanding requests based on sampled latencies.
//
// Note: This operates independently from circuit breaker thresholds (e.g.
// max_connections). Both mechanisms can reject requests, but they act at
From 0be5ca2dad86d47e90309c1a6458d790542e3e77 Mon Sep 17 00:00:00 2001
From: Prashanth Josyula
Date: Wed, 25 Mar 2026 23:05:36 -0700
Subject: [PATCH 11/11] addressing review comments
---
kubernetes/customresourcedefinitions.gen.yaml | 456 ++++++++++--------
networking/v1/destination_rule_alias.gen.go | 46 +-
networking/v1alpha3/destination_rule.pb.go | 374 ++++++++------
networking/v1alpha3/destination_rule.pb.html | 135 ++++--
networking/v1alpha3/destination_rule.proto | 122 +++--
.../v1alpha3/destination_rule_deepcopy.gen.go | 21 +
.../v1alpha3/destination_rule_json.gen.go | 11 +
.../v1beta1/destination_rule_alias.gen.go | 46 +-
8 files changed, 735 insertions(+), 476 deletions(-)
diff --git a/kubernetes/customresourcedefinitions.gen.yaml b/kubernetes/customresourcedefinitions.gen.yaml
index 244e696e43..2d01cac38f 100644
--- a/kubernetes/customresourcedefinitions.gen.yaml
+++ b/kubernetes/customresourcedefinitions.gen.yaml
@@ -482,13 +482,13 @@ spec:
- not:
anyOf:
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
properties:
buffer:
description: Amount added to the measured minRTT
@@ -498,7 +498,44 @@ spec:
minimum: 0
nullable: true
type: integer
- fixedValue:
+ dynamicSampling:
+ description: Periodically sample the minRTT
+ by entering a low-concurrency measurement
+ window.
+ properties:
+ interval:
+ description: The time interval between recalculating
+ the minimum request round-trip time.
+ type: string
+ x-kubernetes-validations:
+ - message: must be a valid duration greater
+ than 1ms
+ rule: duration(self) >= duration('1ms')
+ jitter:
+ description: Randomized time delta that
+ will be introduced to the start of the
+ minRTT calculation window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ minConcurrency:
+ description: The concurrency limit pinned
+ during the minRTT measurement window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ requestCount:
+ description: The number of requests to aggregate/sample
+ during the minRTT recalculation window
+ before updating.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ type: object
+ fixedLatency:
description: A fixed baseline round-trip time
(minRTT) for the upstream, specified as a
duration (e.g., `5ms`, `10ms`).
@@ -507,37 +544,6 @@ spec:
- message: must be a valid duration greater
than 1ms
rule: duration(self) >= duration('1ms')
- interval:
- description: The time interval between recalculating
- the minimum request round-trip time.
- type: string
- x-kubernetes-validations:
- - message: must be a valid duration greater
- than 1ms
- rule: duration(self) >= duration('1ms')
- jitter:
- description: Randomized time delta that will
- be introduced to the start of the minRTT calculation
- window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- minConcurrency:
- description: The concurrency limit pinned during
- the minRTT measurement window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- requestCount:
- description: The number of requests to aggregate/sample
- during the minRTT recalculation window before
- updating.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
type: object
sampleAggregatePercentile:
description: The percentile to use when summarizing
@@ -1542,13 +1548,13 @@ spec:
- not:
anyOf:
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
properties:
buffer:
description: Amount added to the measured minRTT to
@@ -1558,7 +1564,43 @@ spec:
minimum: 0
nullable: true
type: integer
- fixedValue:
+ dynamicSampling:
+ description: Periodically sample the minRTT by entering
+ a low-concurrency measurement window.
+ properties:
+ interval:
+ description: The time interval between recalculating
+ the minimum request round-trip time.
+ type: string
+ x-kubernetes-validations:
+ - message: must be a valid duration greater than
+ 1ms
+ rule: duration(self) >= duration('1ms')
+ jitter:
+ description: Randomized time delta that will be
+ introduced to the start of the minRTT calculation
+ window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ minConcurrency:
+ description: The concurrency limit pinned during
+ the minRTT measurement window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ requestCount:
+ description: The number of requests to aggregate/sample
+ during the minRTT recalculation window before
+ updating.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ type: object
+ fixedLatency:
description: A fixed baseline round-trip time (minRTT)
for the upstream, specified as a duration (e.g.,
`5ms`, `10ms`).
@@ -1566,34 +1608,6 @@ spec:
x-kubernetes-validations:
- message: must be a valid duration greater than 1ms
rule: duration(self) >= duration('1ms')
- interval:
- description: The time interval between recalculating
- the minimum request round-trip time.
- type: string
- x-kubernetes-validations:
- - message: must be a valid duration greater than 1ms
- rule: duration(self) >= duration('1ms')
- jitter:
- description: Randomized time delta that will be introduced
- to the start of the minRTT calculation window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- minConcurrency:
- description: The concurrency limit pinned during the
- minRTT measurement window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- requestCount:
- description: The number of requests to aggregate/sample
- during the minRTT recalculation window before updating.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
type: object
sampleAggregatePercentile:
description: The percentile to use when summarizing aggregated
@@ -2715,13 +2729,13 @@ spec:
- not:
anyOf:
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
properties:
buffer:
description: Amount added to the measured minRTT
@@ -2731,7 +2745,44 @@ spec:
minimum: 0
nullable: true
type: integer
- fixedValue:
+ dynamicSampling:
+ description: Periodically sample the minRTT
+ by entering a low-concurrency measurement
+ window.
+ properties:
+ interval:
+ description: The time interval between recalculating
+ the minimum request round-trip time.
+ type: string
+ x-kubernetes-validations:
+ - message: must be a valid duration greater
+ than 1ms
+ rule: duration(self) >= duration('1ms')
+ jitter:
+ description: Randomized time delta that
+ will be introduced to the start of the
+ minRTT calculation window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ minConcurrency:
+ description: The concurrency limit pinned
+ during the minRTT measurement window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ requestCount:
+ description: The number of requests to aggregate/sample
+ during the minRTT recalculation window
+ before updating.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ type: object
+ fixedLatency:
description: A fixed baseline round-trip time
(minRTT) for the upstream, specified as a
duration (e.g., `5ms`, `10ms`).
@@ -2740,37 +2791,6 @@ spec:
- message: must be a valid duration greater
than 1ms
rule: duration(self) >= duration('1ms')
- interval:
- description: The time interval between recalculating
- the minimum request round-trip time.
- type: string
- x-kubernetes-validations:
- - message: must be a valid duration greater
- than 1ms
- rule: duration(self) >= duration('1ms')
- jitter:
- description: Randomized time delta that will
- be introduced to the start of the minRTT calculation
- window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- minConcurrency:
- description: The concurrency limit pinned during
- the minRTT measurement window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- requestCount:
- description: The number of requests to aggregate/sample
- during the minRTT recalculation window before
- updating.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
type: object
sampleAggregatePercentile:
description: The percentile to use when summarizing
@@ -3775,13 +3795,13 @@ spec:
- not:
anyOf:
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
properties:
buffer:
description: Amount added to the measured minRTT to
@@ -3791,7 +3811,43 @@ spec:
minimum: 0
nullable: true
type: integer
- fixedValue:
+ dynamicSampling:
+ description: Periodically sample the minRTT by entering
+ a low-concurrency measurement window.
+ properties:
+ interval:
+ description: The time interval between recalculating
+ the minimum request round-trip time.
+ type: string
+ x-kubernetes-validations:
+ - message: must be a valid duration greater than
+ 1ms
+ rule: duration(self) >= duration('1ms')
+ jitter:
+ description: Randomized time delta that will be
+ introduced to the start of the minRTT calculation
+ window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ minConcurrency:
+ description: The concurrency limit pinned during
+ the minRTT measurement window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ requestCount:
+ description: The number of requests to aggregate/sample
+ during the minRTT recalculation window before
+ updating.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ type: object
+ fixedLatency:
description: A fixed baseline round-trip time (minRTT)
for the upstream, specified as a duration (e.g.,
`5ms`, `10ms`).
@@ -3799,34 +3855,6 @@ spec:
x-kubernetes-validations:
- message: must be a valid duration greater than 1ms
rule: duration(self) >= duration('1ms')
- interval:
- description: The time interval between recalculating
- the minimum request round-trip time.
- type: string
- x-kubernetes-validations:
- - message: must be a valid duration greater than 1ms
- rule: duration(self) >= duration('1ms')
- jitter:
- description: Randomized time delta that will be introduced
- to the start of the minRTT calculation window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- minConcurrency:
- description: The concurrency limit pinned during the
- minRTT measurement window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- requestCount:
- description: The number of requests to aggregate/sample
- during the minRTT recalculation window before updating.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
type: object
sampleAggregatePercentile:
description: The percentile to use when summarizing aggregated
@@ -4948,13 +4976,13 @@ spec:
- not:
anyOf:
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
properties:
buffer:
description: Amount added to the measured minRTT
@@ -4964,7 +4992,44 @@ spec:
minimum: 0
nullable: true
type: integer
- fixedValue:
+ dynamicSampling:
+ description: Periodically sample the minRTT
+ by entering a low-concurrency measurement
+ window.
+ properties:
+ interval:
+ description: The time interval between recalculating
+ the minimum request round-trip time.
+ type: string
+ x-kubernetes-validations:
+ - message: must be a valid duration greater
+ than 1ms
+ rule: duration(self) >= duration('1ms')
+ jitter:
+ description: Randomized time delta that
+ will be introduced to the start of the
+ minRTT calculation window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ minConcurrency:
+ description: The concurrency limit pinned
+ during the minRTT measurement window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ requestCount:
+ description: The number of requests to aggregate/sample
+ during the minRTT recalculation window
+ before updating.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ type: object
+ fixedLatency:
description: A fixed baseline round-trip time
(minRTT) for the upstream, specified as a
duration (e.g., `5ms`, `10ms`).
@@ -4973,37 +5038,6 @@ spec:
- message: must be a valid duration greater
than 1ms
rule: duration(self) >= duration('1ms')
- interval:
- description: The time interval between recalculating
- the minimum request round-trip time.
- type: string
- x-kubernetes-validations:
- - message: must be a valid duration greater
- than 1ms
- rule: duration(self) >= duration('1ms')
- jitter:
- description: Randomized time delta that will
- be introduced to the start of the minRTT calculation
- window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- minConcurrency:
- description: The concurrency limit pinned during
- the minRTT measurement window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- requestCount:
- description: The number of requests to aggregate/sample
- during the minRTT recalculation window before
- updating.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
type: object
sampleAggregatePercentile:
description: The percentile to use when summarizing
@@ -6008,13 +6042,13 @@ spec:
- not:
anyOf:
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
- required:
- - interval
+ - dynamicSampling
- required:
- - fixedValue
+ - fixedLatency
properties:
buffer:
description: Amount added to the measured minRTT to
@@ -6024,7 +6058,43 @@ spec:
minimum: 0
nullable: true
type: integer
- fixedValue:
+ dynamicSampling:
+ description: Periodically sample the minRTT by entering
+ a low-concurrency measurement window.
+ properties:
+ interval:
+ description: The time interval between recalculating
+ the minimum request round-trip time.
+ type: string
+ x-kubernetes-validations:
+ - message: must be a valid duration greater than
+ 1ms
+ rule: duration(self) >= duration('1ms')
+ jitter:
+ description: Randomized time delta that will be
+ introduced to the start of the minRTT calculation
+ window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ minConcurrency:
+ description: The concurrency limit pinned during
+ the minRTT measurement window.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ requestCount:
+ description: The number of requests to aggregate/sample
+ during the minRTT recalculation window before
+ updating.
+ maximum: 4294967295
+ minimum: 0
+ nullable: true
+ type: integer
+ type: object
+ fixedLatency:
description: A fixed baseline round-trip time (minRTT)
for the upstream, specified as a duration (e.g.,
`5ms`, `10ms`).
@@ -6032,34 +6102,6 @@ spec:
x-kubernetes-validations:
- message: must be a valid duration greater than 1ms
rule: duration(self) >= duration('1ms')
- interval:
- description: The time interval between recalculating
- the minimum request round-trip time.
- type: string
- x-kubernetes-validations:
- - message: must be a valid duration greater than 1ms
- rule: duration(self) >= duration('1ms')
- jitter:
- description: Randomized time delta that will be introduced
- to the start of the minRTT calculation window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- minConcurrency:
- description: The concurrency limit pinned during the
- minRTT measurement window.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
- requestCount:
- description: The number of requests to aggregate/sample
- during the minRTT recalculation window before updating.
- maximum: 4294967295
- minimum: 0
- nullable: true
- type: integer
type: object
sampleAggregatePercentile:
description: The percentile to use when summarizing aggregated
diff --git a/networking/v1/destination_rule_alias.gen.go b/networking/v1/destination_rule_alias.gen.go
index 000262747a..99c08e14d9 100644
--- a/networking/v1/destination_rule_alias.gen.go
+++ b/networking/v1/destination_rule_alias.gen.go
@@ -331,6 +331,21 @@ type OutlierDetection = v1alpha3.OutlierDetection
// load spikes or degraded performance, without requiring operators to manually
// set fixed concurrency thresholds.
//
+// **Important:** When using dynamic sampling (`dynamic_sampling`), the controller
+// periodically enters a minRTT measurement window where the concurrency limit
+// drops to `min_concurrency` (default 3). During this window, requests exceeding
+// that limit are rejected with 503. This can cause a noticeable spike in errors,
+// especially under high traffic. To mitigate this:
+// - Enable client-side retries for 503s, ideally with the `previous_hosts`
+// retry predicate so rejected requests are retried on a different host
+// that is not in a measurement window.
+// - Use `jitter` to stagger measurement windows across hosts.
+// - Consider using `fixed_latency` instead of `dynamic_sampling` if the
+// upstream's baseline latency is well-known and stable.
+//
+// See https://github.com/envoyproxy/envoy/issues/18152 for a real-world
+// example of 503s during minRTT calculation windows.
+//
// See Envoy's
// [adaptive concurrency filter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/adaptive_concurrency_filter)
// for more details.
@@ -357,10 +372,11 @@ type OutlierDetection = v1alpha3.OutlierDetection
// maxConcurrencyLimit: 1000
// concurrencyUpdateInterval: 100ms
// minRttCalcParams:
-// interval: 60s
-// requestCount: 50
-// jitter: 10
-// minConcurrency: 3
+// dynamicSampling:
+// interval: 60s
+// requestCount: 50
+// jitter: 10
+// minConcurrency: 3
// buffer: 25
// concurrencyLimitExceededStatus: 503
//
@@ -376,20 +392,20 @@ type AdaptiveConcurrency_GradientControllerConfig = v1alpha3.AdaptiveConcurrency
// from sampled request latencies.
type AdaptiveConcurrency_GradientControllerConfig_ConcurrencyLimitCalculationParams = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_ConcurrencyLimitCalculationParams
-// Parameters controlling the periodic minRTT recalculation.
+// Parameters controlling how the minRTT (baseline latency) is determined.
// The minRTT is periodically measured by allowing only a very low outstanding
// request count to an upstream cluster and measuring the latency under
// these ideal conditions.
type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams
-// The time interval between recalculating the minimum request round-trip
-// time. Must be >= 1ms.
-//
-// When set, the controller periodically enters a low-concurrency measurement
-// window (pinned to `min_concurrency`) to re-measure the baseline latency.
-// During this window, throughput is temporarily reduced, so longer intervals
-// reduce overhead but may react slower to changes in upstream performance.
-type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Interval = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Interval
+// Parameters for dynamically sampling the minRTT by periodically entering
+// a low-concurrency measurement window.
+type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling
+
+// Periodically sample the minRTT by entering a low-concurrency
+// measurement window. Use this when the upstream's baseline latency
+// may change over time.
+type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling_ = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling_
// A fixed baseline round-trip time (minRTT) for the upstream, specified
// as a duration (e.g., `5ms`, `10ms`). Must be positive. This tells the
@@ -407,8 +423,8 @@ type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_In
//
// Use this when the baseline latency of the upstream is well-known and
// stable, to avoid the periodic low-concurrency measurement windows
-// that dynamic sampling (`interval`) requires.
-type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedValue = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedValue
+// that dynamic sampling requires.
+type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedLatency = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedLatency
// Gradient concurrency control will be used.
type AdaptiveConcurrency_GradientControllerConfig_ = v1alpha3.AdaptiveConcurrency_GradientControllerConfig_
diff --git a/networking/v1alpha3/destination_rule.pb.go b/networking/v1alpha3/destination_rule.pb.go
index 5a32e1ae11..8d88f526aa 100644
--- a/networking/v1alpha3/destination_rule.pb.go
+++ b/networking/v1alpha3/destination_rule.pb.go
@@ -560,7 +560,12 @@ type TrafficPolicy struct {
// Adaptive concurrency settings for dynamically adjusting the allowed number of
// outstanding requests based on sampled latencies.
//
- // Note: This operates independently from circuit breaker thresholds (e.g.
+ // Note: This applies only to HTTP/1.1 and HTTP/2 unary request-response
+ // traffic and is enforced on the server-side (inbound) proxy. It does not
+ // apply to TCP connections, gRPC streaming, or WebSocket connections, since
+ // the filter relies on measuring individual request round-trip latencies.
+ //
+ // This operates independently from circuit breaker thresholds (e.g.
// max_connections). Both mechanisms can reject requests, but they act at
// different layers: adaptive concurrency limits outstanding requests at
// the HTTP filter level before routing, while circuit breakers limit
@@ -1322,6 +1327,21 @@ func (x *OutlierDetection) GetMinHealthPercent() int32 {
// load spikes or degraded performance, without requiring operators to manually
// set fixed concurrency thresholds.
//
+// **Important:** When using dynamic sampling (`dynamic_sampling`), the controller
+// periodically enters a minRTT measurement window where the concurrency limit
+// drops to `min_concurrency` (default 3). During this window, requests exceeding
+// that limit are rejected with 503. This can cause a noticeable spike in errors,
+// especially under high traffic. To mitigate this:
+// - Enable client-side retries for 503s, ideally with the `previous_hosts`
+// retry predicate so rejected requests are retried on a different host
+// that is not in a measurement window.
+// - Use `jitter` to stagger measurement windows across hosts.
+// - Consider using `fixed_latency` instead of `dynamic_sampling` if the
+// upstream's baseline latency is well-known and stable.
+//
+// See https://github.com/envoyproxy/envoy/issues/18152 for a real-world
+// example of 503s during minRTT calculation windows.
+//
// See Envoy's
// [adaptive concurrency filter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/adaptive_concurrency_filter)
// for more details.
@@ -1348,10 +1368,11 @@ func (x *OutlierDetection) GetMinHealthPercent() int32 {
// maxConcurrencyLimit: 1000
// concurrencyUpdateInterval: 100ms
// minRttCalcParams:
-// interval: 60s
-// requestCount: 50
-// jitter: 10
-// minConcurrency: 3
+// dynamicSampling:
+// interval: 60s
+// requestCount: 50
+// jitter: 10
+// minConcurrency: 3
// buffer: 25
// concurrencyLimitExceededStatus: 503
//
@@ -2981,52 +3002,26 @@ func (x *AdaptiveConcurrency_GradientControllerConfig_ConcurrencyLimitCalculatio
return nil
}
-// Parameters controlling the periodic minRTT recalculation.
+// Parameters controlling how the minRTT (baseline latency) is determined.
// The minRTT is periodically measured by allowing only a very low outstanding
// request count to an upstream cluster and measuring the latency under
// these ideal conditions.
type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams struct {
state protoimpl.MessageState `protogen:"open.v1"`
- // Exactly one of `interval` or `fixed_value` must be set to determine
- // how the minRTT is obtained.
+ // Exactly one of `dynamic_sampling` or `fixed_latency` must be set.
//
// Types that are valid to be assigned to MinRttSource:
//
- // *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Interval
- // *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedValue
+ // *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling_
+ // *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedLatency
MinRttSource isAdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_MinRttSource `protobuf_oneof:"min_rtt_source"`
- // The number of requests to aggregate/sample during the minRTT recalculation
- // window before updating. Defaults to 50.
- RequestCount *wrappers.UInt32Value `protobuf:"bytes,2,opt,name=request_count,json=requestCount,proto3" json:"request_count,omitempty"`
- // Randomized time delta that will be introduced to the start of the minRTT
- // calculation window. This is represented as a percentage of the interval duration.
- // Defaults to 15%. Value must be in the range [0, 100].
- // This is recommended to prevent all hosts in a cluster from
- // being in a minRTT calculation window at the same time.
- Jitter *wrappers.UInt32Value `protobuf:"bytes,3,opt,name=jitter,proto3" json:"jitter,omitempty"`
- // The concurrency limit pinned during the minRTT measurement window.
- // Defaults to 3.
- //
- // During the measurement window, the filter drops the concurrency limit to
- // this value to measure latency under near-idle conditions. Requests that
- // exceed this limit during the window are rejected with the configured
- // status code (default 503). The window lasts until `request_count` samples
- // are collected.
- //
- // To mitigate 503s during measurement windows:
- // - Use `jitter` to stagger measurement windows across hosts so they
- // don't all enter the window simultaneously.
- // - Configure retries (with the `previous_hosts` retry predicate) so
- // rejected requests are retried on a different host not currently in
- // a measurement window.
- // - Alternatively, use `fixed_value` instead of `interval` to skip
- // dynamic measurement entirely if the baseline latency is known.
- MinConcurrency *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=min_concurrency,json=minConcurrency,proto3" json:"min_concurrency,omitempty"`
- // Amount added to the measured minRTT to add stability to the concurrency limit
- // during natural variability in latency. This is expressed as a percentage of the
- // measured value and can be adjusted to allow more or less tolerance to the sampled
- // latency values. Defaults to 25%. Value must be in the range [0, 100].
- Buffer *wrappers.UInt32Value `protobuf:"bytes,5,opt,name=buffer,proto3" json:"buffer,omitempty"`
+ // Amount added to the measured minRTT to add stability to the concurrency
+ // limit during natural variability in latency. This is expressed as a
+ // percentage of the measured value and can be adjusted to allow more or
+ // less tolerance to the sampled latency values. Defaults to 25%.
+ // Value must be in the range [0, 100].
+ // This applies regardless of whether minRTT is dynamically sampled or fixed.
+ Buffer *wrappers.UInt32Value `protobuf:"bytes,3,opt,name=buffer,proto3" json:"buffer,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -3068,45 +3063,24 @@ func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParam
return nil
}
-func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetInterval() *duration.Duration {
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetDynamicSampling() *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling {
if x != nil {
- if x, ok := x.MinRttSource.(*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Interval); ok {
- return x.Interval
+ if x, ok := x.MinRttSource.(*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling_); ok {
+ return x.DynamicSampling
}
}
return nil
}
-func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetFixedValue() *duration.Duration {
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetFixedLatency() *duration.Duration {
if x != nil {
- if x, ok := x.MinRttSource.(*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedValue); ok {
- return x.FixedValue
+ if x, ok := x.MinRttSource.(*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedLatency); ok {
+ return x.FixedLatency
}
}
return nil
}
-func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetRequestCount() *wrappers.UInt32Value {
- if x != nil {
- return x.RequestCount
- }
- return nil
-}
-
-func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetJitter() *wrappers.UInt32Value {
- if x != nil {
- return x.Jitter
- }
- return nil
-}
-
-func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetMinConcurrency() *wrappers.UInt32Value {
- if x != nil {
- return x.MinConcurrency
- }
- return nil
-}
-
func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams) GetBuffer() *wrappers.UInt32Value {
if x != nil {
return x.Buffer
@@ -3118,18 +3092,14 @@ type isAdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_
isAdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_MinRttSource()
}
-type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Interval struct {
- // The time interval between recalculating the minimum request round-trip
- // time. Must be >= 1ms.
- //
- // When set, the controller periodically enters a low-concurrency measurement
- // window (pinned to `min_concurrency`) to re-measure the baseline latency.
- // During this window, throughput is temporarily reduced, so longer intervals
- // reduce overhead but may react slower to changes in upstream performance.
- Interval *duration.Duration `protobuf:"bytes,1,opt,name=interval,proto3,oneof"`
+type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling_ struct {
+ // Periodically sample the minRTT by entering a low-concurrency
+ // measurement window. Use this when the upstream's baseline latency
+ // may change over time.
+ DynamicSampling *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling `protobuf:"bytes,1,opt,name=dynamic_sampling,json=dynamicSampling,proto3,oneof"`
}
-type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedValue struct {
+type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedLatency struct {
// A fixed baseline round-trip time (minRTT) for the upstream, specified
// as a duration (e.g., `5ms`, `10ms`). Must be positive. This tells the
// gradient controller "assume the upstream responds in this time under
@@ -3146,14 +3116,116 @@ type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Fi
//
// Use this when the baseline latency of the upstream is well-known and
// stable, to avoid the periodic low-concurrency measurement windows
- // that dynamic sampling (`interval`) requires.
- FixedValue *duration.Duration `protobuf:"bytes,6,opt,name=fixed_value,json=fixedValue,proto3,oneof"`
+ // that dynamic sampling requires.
+ FixedLatency *duration.Duration `protobuf:"bytes,2,opt,name=fixed_latency,json=fixedLatency,proto3,oneof"`
+}
+
+func (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling_) isAdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_MinRttSource() {
+}
+
+func (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedLatency) isAdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_MinRttSource() {
+}
+
+// Parameters for dynamically sampling the minRTT by periodically entering
+// a low-concurrency measurement window.
+type AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // The time interval between recalculating the minimum request round-trip
+ // time. Must be >= 1ms.
+ //
+ // When set, the controller periodically enters a low-concurrency measurement
+ // window (pinned to `min_concurrency`) to re-measure the baseline latency.
+ // During this window, throughput is temporarily reduced, so longer intervals
+ // reduce overhead but may react slower to changes in upstream performance.
+ Interval *duration.Duration `protobuf:"bytes,1,opt,name=interval,proto3" json:"interval,omitempty"`
+ // The number of requests to aggregate/sample during the minRTT
+ // recalculation window before updating. Defaults to 50.
+ RequestCount *wrappers.UInt32Value `protobuf:"bytes,2,opt,name=request_count,json=requestCount,proto3" json:"request_count,omitempty"`
+ // Randomized time delta that will be introduced to the start of the minRTT
+ // calculation window. This is represented as a percentage of the interval
+ // duration. Defaults to 15%. Value must be in the range [0, 100].
+ // This is recommended to prevent all hosts in a cluster from
+ // being in a minRTT calculation window at the same time.
+ Jitter *wrappers.UInt32Value `protobuf:"bytes,3,opt,name=jitter,proto3" json:"jitter,omitempty"`
+ // The concurrency limit pinned during the minRTT measurement window.
+ // Defaults to 3.
+ //
+ // During the measurement window, the filter drops the concurrency limit to
+ // this value to measure latency under near-idle conditions. Requests that
+ // exceed this limit during the window are rejected with the configured
+ // status code (default 503). The window lasts until `request_count` samples
+ // are collected.
+ //
+ // To mitigate 503s during measurement windows:
+ // - Use `jitter` to stagger measurement windows across hosts so they
+ // don't all enter the window simultaneously.
+ // - Configure retries (with the `previous_hosts` retry predicate) so
+ // rejected requests are retried on a different host not currently in
+ // a measurement window.
+ // - Alternatively, use `fixed_latency` instead to skip dynamic
+ // measurement entirely if the baseline latency is known.
+ MinConcurrency *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=min_concurrency,json=minConcurrency,proto3" json:"min_concurrency,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
}
-func (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Interval) isAdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_MinRttSource() {
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) Reset() {
+ *x = AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling{}
+ mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[26]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
}
-func (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedValue) isAdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_MinRttSource() {
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) ProtoMessage() {
+}
+
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) ProtoReflect() protoreflect.Message {
+ mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[26]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling.ProtoReflect.Descriptor instead.
+func (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) Descriptor() ([]byte, []int) {
+ return file_networking_v1alpha3_destination_rule_proto_rawDescGZIP(), []int{7, 0, 1, 0}
+}
+
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) GetInterval() *duration.Duration {
+ if x != nil {
+ return x.Interval
+ }
+ return nil
+}
+
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) GetRequestCount() *wrappers.UInt32Value {
+ if x != nil {
+ return x.RequestCount
+ }
+ return nil
+}
+
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) GetJitter() *wrappers.UInt32Value {
+ if x != nil {
+ return x.Jitter
+ }
+ return nil
+}
+
+func (x *AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling) GetMinConcurrency() *wrappers.UInt32Value {
+ if x != nil {
+ return x.MinConcurrency
+ }
+ return nil
}
// Describes how traffic originating in the 'from' zone or sub-zone is
@@ -3180,7 +3252,7 @@ type LocalityLoadBalancerSetting_Distribute struct {
func (x *LocalityLoadBalancerSetting_Distribute) Reset() {
*x = LocalityLoadBalancerSetting_Distribute{}
- mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[26]
+ mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[27]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3192,7 +3264,7 @@ func (x *LocalityLoadBalancerSetting_Distribute) String() string {
func (*LocalityLoadBalancerSetting_Distribute) ProtoMessage() {}
func (x *LocalityLoadBalancerSetting_Distribute) ProtoReflect() protoreflect.Message {
- mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[26]
+ mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[27]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3242,7 +3314,7 @@ type LocalityLoadBalancerSetting_Failover struct {
func (x *LocalityLoadBalancerSetting_Failover) Reset() {
*x = LocalityLoadBalancerSetting_Failover{}
- mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[27]
+ mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3254,7 +3326,7 @@ func (x *LocalityLoadBalancerSetting_Failover) String() string {
func (*LocalityLoadBalancerSetting_Failover) ProtoMessage() {}
func (x *LocalityLoadBalancerSetting_Failover) ProtoReflect() protoreflect.Message {
- mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[27]
+ mi := &file_networking_v1alpha3_destination_rule_proto_msgTypes[28]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3419,26 +3491,26 @@ const file_networking_v1alpha3_destination_rule_proto_rawDesc = "" +
"\binterval\x18\x02 \x01(\v2\x19.google.protobuf.DurationR\binterval\x12G\n" +
"\x12base_ejection_time\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\x10baseEjectionTime\x120\n" +
"\x14max_ejection_percent\x18\x04 \x01(\x05R\x12maxEjectionPercent\x12,\n" +
- "\x12min_health_percent\x18\x05 \x01(\x05R\x10minHealthPercent\"\xc5\n" +
- "\n" +
+ "\x12min_health_percent\x18\x05 \x01(\x05R\x10minHealthPercent\"\xfe\v\n" +
"\x13AdaptiveConcurrency\x12\x87\x01\n" +
"\x1agradient_controller_config\x18\x01 \x01(\v2G.istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfigH\x00R\x18gradientControllerConfig\x12I\n" +
- "!concurrency_limit_exceeded_status\x18\x03 \x01(\rR\x1econcurrencyLimitExceededStatus\x1a\xb7\b\n" +
+ "!concurrency_limit_exceeded_status\x18\x03 \x01(\rR\x1econcurrencyLimitExceededStatus\x1a\xf0\t\n" +
"\x18GradientControllerConfig\x12\\\n" +
"\x1bsample_aggregate_percentile\x18\x01 \x01(\v2\x1c.google.protobuf.UInt32ValueR\x19sampleAggregatePercentile\x12\xa9\x01\n" +
"\x18concurrency_limit_params\x18\x02 \x01(\v2i.istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParamsB\x04\xe2A\x01\x02R\x16concurrencyLimitParams\x12\x98\x01\n" +
"\x13min_rtt_calc_params\x18\x03 \x01(\v2c.istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParamsB\x04\xe2A\x01\x02R\x10minRttCalcParams\x1a\xd6\x01\n" +
"!ConcurrencyLimitCalculationParams\x12P\n" +
"\x15max_concurrency_limit\x18\x02 \x01(\v2\x1c.google.protobuf.UInt32ValueR\x13maxConcurrencyLimit\x12_\n" +
- "\x1bconcurrency_update_interval\x18\x03 \x01(\v2\x19.google.protobuf.DurationB\x04\xe2A\x01\x02R\x19concurrencyUpdateInterval\x1a\x9c\x03\n" +
- "\x1bMinimumRTTCalculationParams\x127\n" +
- "\binterval\x18\x01 \x01(\v2\x19.google.protobuf.DurationH\x00R\binterval\x12<\n" +
- "\vfixed_value\x18\x06 \x01(\v2\x19.google.protobuf.DurationH\x00R\n" +
- "fixedValue\x12A\n" +
+ "\x1bconcurrency_update_interval\x18\x03 \x01(\v2\x19.google.protobuf.DurationB\x04\xe2A\x01\x02R\x19concurrencyUpdateInterval\x1a\xd5\x04\n" +
+ "\x1bMinimumRTTCalculationParams\x12\xa0\x01\n" +
+ "\x10dynamic_sampling\x18\x01 \x01(\v2s.istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.DynamicSamplingH\x00R\x0fdynamicSampling\x12@\n" +
+ "\rfixed_latency\x18\x02 \x01(\v2\x19.google.protobuf.DurationH\x00R\ffixedLatency\x124\n" +
+ "\x06buffer\x18\x03 \x01(\v2\x1c.google.protobuf.UInt32ValueR\x06buffer\x1a\x88\x02\n" +
+ "\x0fDynamicSampling\x125\n" +
+ "\binterval\x18\x01 \x01(\v2\x19.google.protobuf.DurationR\binterval\x12A\n" +
"\rrequest_count\x18\x02 \x01(\v2\x1c.google.protobuf.UInt32ValueR\frequestCount\x124\n" +
"\x06jitter\x18\x03 \x01(\v2\x1c.google.protobuf.UInt32ValueR\x06jitter\x12E\n" +
- "\x0fmin_concurrency\x18\x04 \x01(\v2\x1c.google.protobuf.UInt32ValueR\x0eminConcurrency\x124\n" +
- "\x06buffer\x18\x05 \x01(\v2\x1c.google.protobuf.UInt32ValueR\x06bufferB\x10\n" +
+ "\x0fmin_concurrency\x18\x04 \x01(\v2\x1c.google.protobuf.UInt32ValueR\x0eminConcurrencyB\x10\n" +
"\x0emin_rtt_sourceB\x1f\n" +
"\x1dconcurrency_controller_config\"\xe4\x03\n" +
"\x11ClientTLSSettings\x12H\n" +
@@ -3490,7 +3562,7 @@ func file_networking_v1alpha3_destination_rule_proto_rawDescGZIP() []byte {
}
var file_networking_v1alpha3_destination_rule_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
-var file_networking_v1alpha3_destination_rule_proto_msgTypes = make([]protoimpl.MessageInfo, 29)
+var file_networking_v1alpha3_destination_rule_proto_msgTypes = make([]protoimpl.MessageInfo, 30)
var file_networking_v1alpha3_destination_rule_proto_goTypes = []any{
(TrafficPolicy_ProxyProtocol_VERSION)(0), // 0: istio.networking.v1alpha3.TrafficPolicy.ProxyProtocol.VERSION
(LoadBalancerSettings_SimpleLB)(0), // 1: istio.networking.v1alpha3.LoadBalancerSettings.SimpleLB
@@ -3520,22 +3592,23 @@ var file_networking_v1alpha3_destination_rule_proto_goTypes = []any{
(*ConnectionPoolSettings_HTTPSettings)(nil), // 25: istio.networking.v1alpha3.ConnectionPoolSettings.HTTPSettings
(*ConnectionPoolSettings_TCPSettings_TcpKeepalive)(nil), // 26: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.TcpKeepalive
(*AdaptiveConcurrency_GradientControllerConfig)(nil), // 27: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig
- (*AdaptiveConcurrency_GradientControllerConfig_ConcurrencyLimitCalculationParams)(nil), // 28: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParams
- (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams)(nil), // 29: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams
- (*LocalityLoadBalancerSetting_Distribute)(nil), // 30: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute
- (*LocalityLoadBalancerSetting_Failover)(nil), // 31: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Failover
- nil, // 32: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute.ToEntry
- (*v1beta1.WorkloadSelector)(nil), // 33: istio.type.v1beta1.WorkloadSelector
- (*duration.Duration)(nil), // 34: google.protobuf.Duration
- (*wrappers.DoubleValue)(nil), // 35: google.protobuf.DoubleValue
- (*wrappers.UInt32Value)(nil), // 36: google.protobuf.UInt32Value
- (*wrappers.BoolValue)(nil), // 37: google.protobuf.BoolValue
- (*PortSelector)(nil), // 38: istio.networking.v1alpha3.PortSelector
+ (*AdaptiveConcurrency_GradientControllerConfig_ConcurrencyLimitCalculationParams)(nil), // 28: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParams
+ (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams)(nil), // 29: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams
+ (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling)(nil), // 30: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.DynamicSampling
+ (*LocalityLoadBalancerSetting_Distribute)(nil), // 31: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute
+ (*LocalityLoadBalancerSetting_Failover)(nil), // 32: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Failover
+ nil, // 33: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute.ToEntry
+ (*v1beta1.WorkloadSelector)(nil), // 34: istio.type.v1beta1.WorkloadSelector
+ (*duration.Duration)(nil), // 35: google.protobuf.Duration
+ (*wrappers.DoubleValue)(nil), // 36: google.protobuf.DoubleValue
+ (*wrappers.UInt32Value)(nil), // 37: google.protobuf.UInt32Value
+ (*wrappers.BoolValue)(nil), // 38: google.protobuf.BoolValue
+ (*PortSelector)(nil), // 39: istio.networking.v1alpha3.PortSelector
}
var file_networking_v1alpha3_destination_rule_proto_depIdxs = []int32{
5, // 0: istio.networking.v1alpha3.DestinationRule.traffic_policy:type_name -> istio.networking.v1alpha3.TrafficPolicy
6, // 1: istio.networking.v1alpha3.DestinationRule.subsets:type_name -> istio.networking.v1alpha3.Subset
- 33, // 2: istio.networking.v1alpha3.DestinationRule.workload_selector:type_name -> istio.type.v1beta1.WorkloadSelector
+ 34, // 2: istio.networking.v1alpha3.DestinationRule.workload_selector:type_name -> istio.type.v1beta1.WorkloadSelector
7, // 3: istio.networking.v1alpha3.TrafficPolicy.load_balancer:type_name -> istio.networking.v1alpha3.LoadBalancerSettings
9, // 4: istio.networking.v1alpha3.TrafficPolicy.connection_pool:type_name -> istio.networking.v1alpha3.ConnectionPoolSettings
10, // 5: istio.networking.v1alpha3.TrafficPolicy.outlier_detection:type_name -> istio.networking.v1alpha3.OutlierDetection
@@ -3550,61 +3623,62 @@ var file_networking_v1alpha3_destination_rule_proto_depIdxs = []int32{
1, // 14: istio.networking.v1alpha3.LoadBalancerSettings.simple:type_name -> istio.networking.v1alpha3.LoadBalancerSettings.SimpleLB
19, // 15: istio.networking.v1alpha3.LoadBalancerSettings.consistent_hash:type_name -> istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB
13, // 16: istio.networking.v1alpha3.LoadBalancerSettings.locality_lb_setting:type_name -> istio.networking.v1alpha3.LocalityLoadBalancerSetting
- 34, // 17: istio.networking.v1alpha3.LoadBalancerSettings.warmup_duration_secs:type_name -> google.protobuf.Duration
+ 35, // 17: istio.networking.v1alpha3.LoadBalancerSettings.warmup_duration_secs:type_name -> google.protobuf.Duration
8, // 18: istio.networking.v1alpha3.LoadBalancerSettings.warmup:type_name -> istio.networking.v1alpha3.WarmupConfiguration
- 34, // 19: istio.networking.v1alpha3.WarmupConfiguration.duration:type_name -> google.protobuf.Duration
- 35, // 20: istio.networking.v1alpha3.WarmupConfiguration.minimum_percent:type_name -> google.protobuf.DoubleValue
- 35, // 21: istio.networking.v1alpha3.WarmupConfiguration.aggression:type_name -> google.protobuf.DoubleValue
+ 35, // 19: istio.networking.v1alpha3.WarmupConfiguration.duration:type_name -> google.protobuf.Duration
+ 36, // 20: istio.networking.v1alpha3.WarmupConfiguration.minimum_percent:type_name -> google.protobuf.DoubleValue
+ 36, // 21: istio.networking.v1alpha3.WarmupConfiguration.aggression:type_name -> google.protobuf.DoubleValue
24, // 22: istio.networking.v1alpha3.ConnectionPoolSettings.tcp:type_name -> istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings
25, // 23: istio.networking.v1alpha3.ConnectionPoolSettings.http:type_name -> istio.networking.v1alpha3.ConnectionPoolSettings.HTTPSettings
- 36, // 24: istio.networking.v1alpha3.OutlierDetection.consecutive_local_origin_failures:type_name -> google.protobuf.UInt32Value
- 36, // 25: istio.networking.v1alpha3.OutlierDetection.consecutive_gateway_errors:type_name -> google.protobuf.UInt32Value
- 36, // 26: istio.networking.v1alpha3.OutlierDetection.consecutive_5xx_errors:type_name -> google.protobuf.UInt32Value
- 34, // 27: istio.networking.v1alpha3.OutlierDetection.interval:type_name -> google.protobuf.Duration
- 34, // 28: istio.networking.v1alpha3.OutlierDetection.base_ejection_time:type_name -> google.protobuf.Duration
+ 37, // 24: istio.networking.v1alpha3.OutlierDetection.consecutive_local_origin_failures:type_name -> google.protobuf.UInt32Value
+ 37, // 25: istio.networking.v1alpha3.OutlierDetection.consecutive_gateway_errors:type_name -> google.protobuf.UInt32Value
+ 37, // 26: istio.networking.v1alpha3.OutlierDetection.consecutive_5xx_errors:type_name -> google.protobuf.UInt32Value
+ 35, // 27: istio.networking.v1alpha3.OutlierDetection.interval:type_name -> google.protobuf.Duration
+ 35, // 28: istio.networking.v1alpha3.OutlierDetection.base_ejection_time:type_name -> google.protobuf.Duration
27, // 29: istio.networking.v1alpha3.AdaptiveConcurrency.gradient_controller_config:type_name -> istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig
3, // 30: istio.networking.v1alpha3.ClientTLSSettings.mode:type_name -> istio.networking.v1alpha3.ClientTLSSettings.TLSmode
- 37, // 31: istio.networking.v1alpha3.ClientTLSSettings.insecure_skip_verify:type_name -> google.protobuf.BoolValue
- 30, // 32: istio.networking.v1alpha3.LocalityLoadBalancerSetting.distribute:type_name -> istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute
- 31, // 33: istio.networking.v1alpha3.LocalityLoadBalancerSetting.failover:type_name -> istio.networking.v1alpha3.LocalityLoadBalancerSetting.Failover
- 37, // 34: istio.networking.v1alpha3.LocalityLoadBalancerSetting.enabled:type_name -> google.protobuf.BoolValue
- 38, // 35: istio.networking.v1alpha3.TrafficPolicy.PortTrafficPolicy.port:type_name -> istio.networking.v1alpha3.PortSelector
+ 38, // 31: istio.networking.v1alpha3.ClientTLSSettings.insecure_skip_verify:type_name -> google.protobuf.BoolValue
+ 31, // 32: istio.networking.v1alpha3.LocalityLoadBalancerSetting.distribute:type_name -> istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute
+ 32, // 33: istio.networking.v1alpha3.LocalityLoadBalancerSetting.failover:type_name -> istio.networking.v1alpha3.LocalityLoadBalancerSetting.Failover
+ 38, // 34: istio.networking.v1alpha3.LocalityLoadBalancerSetting.enabled:type_name -> google.protobuf.BoolValue
+ 39, // 35: istio.networking.v1alpha3.TrafficPolicy.PortTrafficPolicy.port:type_name -> istio.networking.v1alpha3.PortSelector
7, // 36: istio.networking.v1alpha3.TrafficPolicy.PortTrafficPolicy.load_balancer:type_name -> istio.networking.v1alpha3.LoadBalancerSettings
9, // 37: istio.networking.v1alpha3.TrafficPolicy.PortTrafficPolicy.connection_pool:type_name -> istio.networking.v1alpha3.ConnectionPoolSettings
10, // 38: istio.networking.v1alpha3.TrafficPolicy.PortTrafficPolicy.outlier_detection:type_name -> istio.networking.v1alpha3.OutlierDetection
12, // 39: istio.networking.v1alpha3.TrafficPolicy.PortTrafficPolicy.tls:type_name -> istio.networking.v1alpha3.ClientTLSSettings
0, // 40: istio.networking.v1alpha3.TrafficPolicy.ProxyProtocol.version:type_name -> istio.networking.v1alpha3.TrafficPolicy.ProxyProtocol.VERSION
- 35, // 41: istio.networking.v1alpha3.TrafficPolicy.RetryBudget.percent:type_name -> google.protobuf.DoubleValue
+ 36, // 41: istio.networking.v1alpha3.TrafficPolicy.RetryBudget.percent:type_name -> google.protobuf.DoubleValue
22, // 42: istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.http_cookie:type_name -> istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.HTTPCookie
20, // 43: istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.ring_hash:type_name -> istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.RingHash
21, // 44: istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.maglev:type_name -> istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.MagLev
- 34, // 45: istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.HTTPCookie.ttl:type_name -> google.protobuf.Duration
+ 35, // 45: istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.HTTPCookie.ttl:type_name -> google.protobuf.Duration
23, // 46: istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.HTTPCookie.attributes:type_name -> istio.networking.v1alpha3.LoadBalancerSettings.ConsistentHashLB.HTTPCookie.Attribute
- 34, // 47: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.connect_timeout:type_name -> google.protobuf.Duration
+ 35, // 47: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.connect_timeout:type_name -> google.protobuf.Duration
26, // 48: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.tcp_keepalive:type_name -> istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.TcpKeepalive
- 34, // 49: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.max_connection_duration:type_name -> google.protobuf.Duration
- 34, // 50: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.idle_timeout:type_name -> google.protobuf.Duration
- 34, // 51: istio.networking.v1alpha3.ConnectionPoolSettings.HTTPSettings.idle_timeout:type_name -> google.protobuf.Duration
+ 35, // 49: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.max_connection_duration:type_name -> google.protobuf.Duration
+ 35, // 50: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.idle_timeout:type_name -> google.protobuf.Duration
+ 35, // 51: istio.networking.v1alpha3.ConnectionPoolSettings.HTTPSettings.idle_timeout:type_name -> google.protobuf.Duration
2, // 52: istio.networking.v1alpha3.ConnectionPoolSettings.HTTPSettings.h2_upgrade_policy:type_name -> istio.networking.v1alpha3.ConnectionPoolSettings.HTTPSettings.H2UpgradePolicy
- 34, // 53: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.TcpKeepalive.time:type_name -> google.protobuf.Duration
- 34, // 54: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.TcpKeepalive.interval:type_name -> google.protobuf.Duration
- 36, // 55: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.sample_aggregate_percentile:type_name -> google.protobuf.UInt32Value
+ 35, // 53: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.TcpKeepalive.time:type_name -> google.protobuf.Duration
+ 35, // 54: istio.networking.v1alpha3.ConnectionPoolSettings.TCPSettings.TcpKeepalive.interval:type_name -> google.protobuf.Duration
+ 37, // 55: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.sample_aggregate_percentile:type_name -> google.protobuf.UInt32Value
28, // 56: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.concurrency_limit_params:type_name -> istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParams
29, // 57: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.min_rtt_calc_params:type_name -> istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams
- 36, // 58: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParams.max_concurrency_limit:type_name -> google.protobuf.UInt32Value
- 34, // 59: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParams.concurrency_update_interval:type_name -> google.protobuf.Duration
- 34, // 60: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.interval:type_name -> google.protobuf.Duration
- 34, // 61: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.fixed_value:type_name -> google.protobuf.Duration
- 36, // 62: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.request_count:type_name -> google.protobuf.UInt32Value
- 36, // 63: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.jitter:type_name -> google.protobuf.UInt32Value
- 36, // 64: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.min_concurrency:type_name -> google.protobuf.UInt32Value
- 36, // 65: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.buffer:type_name -> google.protobuf.UInt32Value
- 32, // 66: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute.to:type_name -> istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute.ToEntry
- 67, // [67:67] is the sub-list for method output_type
- 67, // [67:67] is the sub-list for method input_type
- 67, // [67:67] is the sub-list for extension type_name
- 67, // [67:67] is the sub-list for extension extendee
- 0, // [0:67] is the sub-list for field type_name
+ 37, // 58: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParams.max_concurrency_limit:type_name -> google.protobuf.UInt32Value
+ 35, // 59: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.ConcurrencyLimitCalculationParams.concurrency_update_interval:type_name -> google.protobuf.Duration
+ 30, // 60: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.dynamic_sampling:type_name -> istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.DynamicSampling
+ 35, // 61: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.fixed_latency:type_name -> google.protobuf.Duration
+ 37, // 62: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.buffer:type_name -> google.protobuf.UInt32Value
+ 35, // 63: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.DynamicSampling.interval:type_name -> google.protobuf.Duration
+ 37, // 64: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.DynamicSampling.request_count:type_name -> google.protobuf.UInt32Value
+ 37, // 65: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.DynamicSampling.jitter:type_name -> google.protobuf.UInt32Value
+ 37, // 66: istio.networking.v1alpha3.AdaptiveConcurrency.GradientControllerConfig.MinimumRTTCalculationParams.DynamicSampling.min_concurrency:type_name -> google.protobuf.UInt32Value
+ 33, // 67: istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute.to:type_name -> istio.networking.v1alpha3.LocalityLoadBalancerSetting.Distribute.ToEntry
+ 68, // [68:68] is the sub-list for method output_type
+ 68, // [68:68] is the sub-list for method input_type
+ 68, // [68:68] is the sub-list for extension type_name
+ 68, // [68:68] is the sub-list for extension extendee
+ 0, // [0:68] is the sub-list for field type_name
}
func init() { file_networking_v1alpha3_destination_rule_proto_init() }
@@ -3629,8 +3703,8 @@ func file_networking_v1alpha3_destination_rule_proto_init() {
(*LoadBalancerSettings_ConsistentHashLB_Maglev)(nil),
}
file_networking_v1alpha3_destination_rule_proto_msgTypes[25].OneofWrappers = []any{
- (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_Interval)(nil),
- (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedValue)(nil),
+ (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_DynamicSampling_)(nil),
+ (*AdaptiveConcurrency_GradientControllerConfig_MinimumRTTCalculationParams_FixedLatency)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -3638,7 +3712,7 @@ func file_networking_v1alpha3_destination_rule_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_networking_v1alpha3_destination_rule_proto_rawDesc), len(file_networking_v1alpha3_destination_rule_proto_rawDesc)),
NumEnums: 4,
- NumMessages: 29,
+ NumMessages: 30,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/networking/v1alpha3/destination_rule.pb.html b/networking/v1alpha3/destination_rule.pb.html
index eb869639f4..142a724564 100644
--- a/networking/v1alpha3/destination_rule.pb.html
+++ b/networking/v1alpha3/destination_rule.pb.html
@@ -6,7 +6,7 @@
generator: protoc-gen-docs
schema: istio.networking.v1alpha3.DestinationRule
aliases: [/docs/reference/config/networking/v1alpha3/destination-rule]
-number_of_entries: 32
+number_of_entries: 33
---
DestinationRule defines policies that apply to traffic intended for a
service after routing has occurred. These rules specify configuration
@@ -285,7 +285,11 @@
TrafficPolicy
Adaptive concurrency settings for dynamically adjusting the allowed number of
outstanding requests based on sampled latencies.
-Note: This operates independently from circuit breaker thresholds (e.g.
+ Note: This applies only to HTTP/1.1 and HTTP/2 unary request-response
+traffic and is enforced on the server-side (inbound) proxy. It does not
+apply to TCP connections, gRPC streaming, or WebSocket connections, since
+the filter relies on measuring individual request round-trip latencies.
+This operates independently from circuit breaker thresholds (e.g.
max_connections). Both mechanisms can reject requests, but they act at
different layers: adaptive concurrency limits outstanding requests at
the HTTP filter level before routing, while circuit breakers limit
@@ -1514,6 +1518,21 @@ AdaptiveConcurrency
This is useful for protecting upstream services from being overwhelmed during
load spikes or degraded performance, without requiring operators to manually
set fixed concurrency thresholds.
+Important: When using dynamic sampling (dynamic_sampling), the controller
+periodically enters a minRTT measurement window where the concurrency limit
+drops to min_concurrency (default 3). During this window, requests exceeding
+that limit are rejected with 503. This can cause a noticeable spike in errors,
+especially under high traffic. To mitigate this:
+
+- Enable client-side retries for 503s, ideally with the
previous_hosts
+retry predicate so rejected requests are retried on a different host
+that is not in a measurement window.
+- Use
jitter to stagger measurement windows across hosts.
+- Consider using
fixed_latency instead of dynamic_sampling if the
+upstream’s baseline latency is well-known and stable.
+See https://github.com/envoyproxy/envoy/issues/18152 for a real-world
+example of 503s during minRTT calculation windows.
+
See Envoy’s
adaptive concurrency filter
for more details.
@@ -1534,10 +1553,11 @@ AdaptiveConcurrency
maxConcurrencyLimit: 1000
concurrencyUpdateInterval: 100ms
minRttCalcParams:
- interval: 60s
- requestCount: 50
- jitter: 10
- minConcurrency: 3
+ dynamicSampling:
+ interval: 60s
+ requestCount: 50
+ jitter: 10
+ minConcurrency: 3
buffer: 25
concurrencyLimitExceededStatus: 503
@@ -1672,7 +1692,7 @@ MinimumRTTCalculationParams
-Parameters controlling the periodic minRTT recalculation.
+ Parameters controlling how the minRTT (baseline latency) is determined.
The minRTT is periodically measured by allowing only a very low outstanding
request count to an upstream cluster and measuring the latency under
these ideal conditions.
@@ -1685,22 +1705,19 @@
-
-
+
+ |
- The time interval between recalculating the minimum request round-trip
-time. Must be >= 1ms.
-When set, the controller periodically enters a low-concurrency measurement
-window (pinned to min_concurrency) to re-measure the baseline latency.
-During this window, throughput is temporarily reduced, so longer intervals
-reduce overhead but may react slower to changes in upstream performance.
+Periodically sample the minRTT by entering a low-concurrency
+measurement window. Use this when the upstream’s baseline latency
+may change over time.
|
-
-
+
+ |
@@ -1716,35 +1733,79 @@
+ |
+
+ Amount added to the measured minRTT to add stability to the concurrency
+limit during natural variability in latency. This is expressed as a
+percentage of the measured value and can be adjusted to allow more or
+less tolerance to the sampled latency values. Defaults to 25%.
+Value must be in the range [0, 100].
+This applies regardless of whether minRTT is dynamically sampled or fixed.
+
+ |
+ |
+ | | | |