This is the "latest" release of Envoy Gateway, which contains the most recent commits from the main branch.
This release might not be stable.
Please refer to the /docs documentation for the most current information.
BackendTrafficPolicy
6 minute read
Before you Begin
Overview
BackendTrafficPolicy is an extension to the Kubernetes Gateway API that controls how Envoy Gateway communicates with your backend services. It can configure connection behavior, resilience mechanisms, and performance optimizations without requiring changes to your applications.
Think of it as a traffic controller between your gateway and backend services. It can detect problems, prevent failures from spreading, and optimize request handling to improve system stability.
Use Cases
BackendTrafficPolicy is particularly useful in scenarios where you need to:
Protect your services: Limit connections and reject excess traffic when necessary
Build resilient systems: Detect failing services and redirect traffic
Improve performance: Optimize how requests are distributed and responses are handled
Test system behavior: Inject faults and validate your recovery mechanisms
BackendTrafficPolicy in Envoy Gateway
BackendTrafficPolicy is part of the Envoy Gateway API suite, which extends the Kubernetes Gateway API with additional capabilities. It’s implemented as a Custom Resource Definition (CRD) that you can use to configure how Envoy Gateway manages traffic to your backend services.
Targets
BackendTrafficPolicy can be attached to Gateway API resources using two targeting mechanisms:
- Direct Reference (
targetRefs): Explicitly reference specific resources by name and kind. - Label Selection (
targetSelectors): Match resources based on their labels (see targetSelectors API reference)
# Direct reference targeting
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: direct-policy
spec:
targetRefs:
- kind: HTTPRoute
name: my-route
circuitBreaker:
maxConnections: 50
---
# Label-based targeting
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: selector-policy
spec:
targetSelectors:
- kind: HTTPRoute
matchLabels:
app: payment-service
rateLimit:
local:
requests: 10
unit: Second
The policy applies to all resources that match either targeting method. You can target various Gateway API resource types including
Gateway, ListenerSet, HTTPRoute, GRPCRoute, TCPRoute, UDPRoute, TLSRoute.
When a BackendTrafficPolicy targets a ListenerSet, it applies only to listeners in that ListenerSet. It does not apply to listeners owned directly by the parent Gateway. A ListenerSet target can also use sectionName to apply the policy to a single listener in the ListenerSet.
Route-level policies apply to the targeted route regardless of whether that route is attached directly to a Gateway or through a ListenerSet.
Important: A BackendTrafficPolicy can only target resources in the same namespace as the policy itself.
Precedence
When multiple BackendTrafficPolicies apply to the same resource, Envoy Gateway resolves conflicts using a precedence hierarchy based on the target resource type, route attachment path, and section-level specificity.
Route-specific policies take precedence first:
- Route rule-level policies (HTTPRoute/GRPCRoute with
sectionNametargeting specific rules) - Route-level policies (HTTPRoute, GRPCRoute without
sectionName)
After route-specific policies, parent policy precedence depends on how the route is attached.
For routes attached through a ListenerSet:
- ListenerSet listener-level policies (
ListenerSetwithsectionNametargeting a specific ListenerSet listener) - ListenerSet-level policies (
ListenerSetwithoutsectionName) - Gateway-level policies (
GatewaywithoutsectionName) on the parent Gateway
For routes attached directly to a Gateway:
- Gateway listener-level policies (
GatewaywithsectionNametargeting specific Gateway-owned listeners) - Gateway-level policies (
GatewaywithoutsectionName)
Gateway listener-level policies are sibling scopes to ListenerSet listeners and do not apply to routes attached through a ListenerSet.
# Gateway-level policy (lower precedence) - Applies to all routes in the gateway
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: gateway-policy
spec:
targetRefs:
- kind: Gateway
name: my-gateway
circuitBreaker:
maxConnections: 100
---
# Route-level policy (higher precedence)
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: route-policy
spec:
targetRefs:
- kind: HTTPRoute
name: my-route
circuitBreaker:
maxConnections: 50
In this example, the HTTPRoute my-route would use maxConnections: 50 from the route-level policy, overriding the gateway-level setting of 100.
Multiple Policies at the Same Level
When multiple BackendTrafficPolicies target the same resource at the same hierarchy level (e.g., multiple policies targeting the same HTTPRoute), Envoy Gateway uses the following tie-breaking rules:
- Creation Time Priority: The oldest policy (earliest
creationTimestamp) takes precedence - Name-based Sorting: If policies have identical creation timestamps, they are sorted alphabetically by namespaced name, with the first policy taking precedence
# Policy created first - takes precedence
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: alpha-policy
creationTimestamp: "2023-01-01T10:00:00Z"
spec:
targetRefs:
- kind: HTTPRoute
name: my-route
circuitBreaker:
maxConnections: 30
---
# Policy created later - lower precedence
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: beta-policy
creationTimestamp: "2023-01-01T11:00:00Z"
spec:
targetRefs:
- kind: HTTPRoute
name: my-route
circuitBreaker:
maxConnections: 40
In this example, alpha-policy would take precedence due to its earlier creation time, so the HTTPRoute would use maxConnections: 30.
When the mergeType field is unset, no merging occurs and only the most specific configuration takes effect. However, policies can be configured to merge with parent policies using the mergeType field (see Policy Merging section below).
Policy Merging
BackendTrafficPolicy supports merging configurations using the mergeType field, which allows route-level or route rule-level policies to combine with parent policies rather than completely overriding them. This enables layered policy strategies where platform teams can set baseline configurations at the Gateway or ListenerSet level, while application teams can add specific policies for their routes.
When merging occurs, route-level policies merge with the closest parent policy in the route’s attachment hierarchy:
- For routes attached directly to a Gateway, the route policy first looks for a Gateway listener-level policy, then a Gateway-level policy.
- For routes attached through a ListenerSet, the route policy first looks for a ListenerSet listener-level policy, then a ListenerSet-level policy, then the parent Gateway-level policy.
A route policy attached through a ListenerSet does not merge with a Gateway listener-level policy because Gateway listeners and ListenerSet listeners are sibling scopes.
Merge Types
- StrategicMerge: Uses Kubernetes strategic merge patch semantics, providing intelligent merging for complex data structures including arrays
- JSONMerge: Uses RFC 7396 JSON Merge Patch semantics, with simple replacement strategy where arrays are completely replaced
Example Usage
Here’s an example demonstrating policy merging for rate limiting:
# Platform team: Gateway-level policy with global abuse prevention
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: global-backendtrafficpolicy
spec:
rateLimit:
global:
rules:
- clientSelectors:
- sourceCIDR:
type: Distinct
value: 0.0.0.0/0
limit:
requests: 100
unit: Second
shared: true
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: eg
---
# Application team: Route-level policy with specific limits
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: route-backendtrafficpolicy
spec:
mergeType: StrategicMerge # Enables merging with gateway policy
rateLimit:
global:
rules:
- clientSelectors:
- sourceCIDR:
type: Distinct
value: 0.0.0.0/0
limit:
requests: 5
unit: Minute
shared: false
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: signup-service-httproute
In this example, the route-level policy merges with the gateway-level policy, resulting in both rate limits being enforced: the global 100 requests/second abuse limit and the route-specific 5 requests/minute limit.
Key Constraints
- The
mergeTypefield can only be set on policies targeting xRoute resources (like HTTPRoute), not parent resources (like Gateway or ListenerSet) - When
mergeTypeis unset, no merging occurs - only the most specific policy takes effect - The merged configuration combines both policies, enabling layered protection strategies
Related Resources
- Circuit Breakers
- Failover
- Fault Injection
- Global Rate Limit
- Local Rate Limit
- Load Balancing
- Response Compression
- Response Override
- BackendTrafficPolicy API Reference
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.