Envoy's xDS APIs are split into LDS, RDS, CDS and EDS (plus SDS). What does each one deliver, and how do they depend on one another?
answer
- one API per resource type
- listener names a route, route names a cluster
- endpoints churn most, so they got their own stream
- references point down, updates arrive bottom-up
- CDS, EDS, LDS, RDS
basics
~20 sLDS delivers listeners, RDS the route tables they name, CDS the upstream clusters routes point at, EDS the endpoint addresses inside those clusters, and SDS the TLS secrets. The dependency runs listener to route to cluster to endpoint, which is why updates are ordered CDS, EDS, LDS, RDS.
solid answer
~50 sThey are four subscriptions to four resource types, arranged as a reference chain. **LDS** sends listeners — a socket plus its filter chains. An HTTP listener's `http_connection_manager` either carries its routes inline or names them, and **RDS** supplies that named `RouteConfiguration` with its `virtual_hosts`. A route action names a cluster, and **CDS** supplies the `Cluster` — its load-balancing policy, timeouts and circuit-breaker settings. If that cluster's discovery type is `EDS`, its actual addresses come separately from **EDS** as a `ClusterLoadAssignment`, which is what lets endpoints churn constantly without ever resending a cluster definition. **SDS** delivers certificates and keys to listeners and clusters, so private keys stay off disk. Because references point downward, Envoy's recommended update order is the reverse: CDS, then EDS, then LDS, then RDS — the thing being referenced arrives before the thing referencing it.
go deeper
Learn the four names and what each carries: listeners, routes, clusters, endpoints. Being able to say which one delivers upstream addresses already puts you ahead of most candidates.
Explain the reference chain and why the update order is CDS, EDS, LDS, RDS. Expect to be asked why endpoints were split away from clusters at all.
Show judgment about which layers you make dynamic in a given deployment — static listeners with dynamic routes at the edge, everything dynamic in a sidecar — and what each choice costs you when the control plane is unavailable.
Own the split as an API design decision: resource granularity determines push volume, blast radius and control-plane cost, and the scale extensions (VHDS, SRDS) exist because that granularity stops paying at very large route tables.
## Four resources, one reference chain Envoy's configuration is a graph, and xDS splits that graph along its natural seams. Each discovery service carries exactly one node type, and the split is not arbitrary: it follows how often each part changes. **LDS — listeners.** A `Listener` is an address Envoy binds plus the filter chains that handle what arrives there. For HTTP that chain contains the `http_connection_manager` (HCM) network filter, which itself holds a chain of HTTP filters and a routing decision. Listeners change rarely — a new port is a deliberate act. **RDS — route configurations.** Inside the HCM you either write `route_config` inline or write: ```yaml rds: route_config_name: local_route config_source: { ads: {} } ``` That name is a pointer. RDS then delivers a `RouteConfiguration` containing `virtual_hosts`, each with `domains` and `routes`, and each route action naming a cluster. Routes change every time someone shifts traffic, so they get their own subscription, and a route push does not disturb the listener or its open connections. **CDS — clusters.** A `Cluster` is the definition of an upstream: its name, discovery type, load-balancing policy, connect timeout, health checking, circuit breakers, upstream TLS. It is the *shape* of a destination, not its membership. **EDS — endpoints.** When a cluster sets `type: EDS`, its membership arrives separately as a `ClusterLoadAssignment` keyed by the cluster's EDS service name. This is the highest-churn resource in the system: instances restart, autoscaling adds capacity, a health check ejects one. Splitting it from CDS means an endpoint change costs one small EDS message and touches nothing else in the config. **SDS — secrets.** TLS certificates, private keys and validation contexts, referenced by name from a listener's or cluster's TLS context. Its real value is operational: certificates can be rotated, and short-lived ones issued, without the private key ever being written to the proxy's filesystem or embedded in a pushed cluster definition. ## Why the order matters Because references point downward — listener → route config → cluster → endpoints — an update that adds the referencing object before the referenced one leaves a dangling pointer for as long as the gap lasts. A route naming a cluster Envoy has never heard of produces a 503 for every request that matches it; a listener whose route configuration has not arrived cannot route anything. Envoy's documented sequence for a client applying updates is therefore **CDS, EDS, LDS, RDS** — sometimes called *make before break*: create the thing that will be referenced, then create the reference. Deletion runs the other way: remove the reference first, then the resource, so nothing points at a resource in the middle of being torn down. This ordering is only enforceable when all four types travel on one stream, which is exactly the argument for the aggregated stream. With independent subscriptions the resource types are separate connections with no relative ordering guarantee at all. ## Not every resource has to be dynamic The types are independent, and mixing is normal. A common sidecar layout is dynamic everything. A common edge-proxy layout is a static listener with a static filter chain (nobody is redefining the ports on your ingress), CDS+EDS for the upstreams, and RDS for the routes because that is where traffic-shifting work happens. A cluster can also skip EDS entirely and use `STRICT_DNS` or `LOGICAL_DNS`, in which case Envoy resolves the name itself and no EDS subscription exists for it — worth knowing because "endpoints are stale" has a completely different investigation depending on which one you chose. ## Naming and subscriptions LDS and CDS are *wildcard* subscriptions: Envoy asks for everything it should have, and the management server decides what that is from the `node` identity presented on connect. RDS, EDS and SDS are subscriptions **by name** — Envoy asks for exactly the route configurations, EDS service names and secrets that the resources it already holds referred to. This is why the flow is naturally staged: Envoy cannot ask for an endpoint set until a cluster has told it that set exists. It also explains a common confusion in debugging. If a route configuration never arrives, the first question is not "is the control plane broken" but "did any listener actually name this route config?" — because if nothing named it, Envoy never subscribed to it. ## Beyond the four The family has more members, worth naming but not memorising: VHDS for delivering individual virtual hosts on demand, SRDS for scoped route configurations, RTDS for runtime layers, and ECDS for extension configuration. They exist for scale problems — a proxy that would otherwise hold a route table with tens of thousands of virtual hosts. Knowing they exist is enough; knowing LDS/RDS/CDS/EDS/SDS cold is not optional.
- Why is endpoint data split out into EDS instead of being part of the Cluster resource CDS already delivers?Churn rate. A cluster's shape — LB policy, timeouts, circuit breakers, TLS — changes when someone edits config; its membership changes constantly as instances come and go. Separating them means an instance replacement pushes one small `ClusterLoadAssignment` rather than resending a full cluster definition, and it avoids re-running cluster construction (and its warming) for what is only a membership change.
- If a Cluster uses STRICT_DNS instead of EDS, what changes about how it gets its endpoints?Envoy resolves the configured hostname itself on a refresh interval and uses every returned address as an endpoint, so there is no EDS subscription for that cluster at all. That trades control-plane precision for independence: it keeps working if the control plane is down, but membership is only as fresh and as granular as DNS, with no per-endpoint metadata, locality or weighting.
- A route configuration is never delivered to a proxy. Before blaming the control plane, what would you check?Whether anything subscribed to it. RDS is a by-name subscription: Envoy asks only for route configuration names that a listener's `http_connection_manager` actually referenced via `rds.route_config_name`. If no listener names it — or the listener carries inline routes instead — the proxy never requested it, and the control plane is correctly sending nothing.
Think of it as a set of pointers: the listener holds the name of a route table, a route holds the name of a cluster, and the cluster holds the name of an endpoint set. Each name is resolved by a different subscription, so each can be updated on its own schedule.
saying these in an interview costs you the question
- Thinks CDS delivers the endpoint addresses too
- Believes LDS must always come first because listeners are 'the front door'
- Cannot say what RDS adds over inline routes in the listener
- Assumes every cluster has an EDS subscription
- Treats SDS as optional decoration rather than how keys stay off disk