CONCEPT Cited by 1 source
ETag conditional polling¶
Definition¶
ETag conditional polling is a cache-coherence protocol in which a client on each poll sends its last-seen ETag (an opaque fingerprint of the resource) and the server replies:
304 Not Modifiedwith an empty body if its current ETag matches (no change; client keeps its cached copy), or200 OKwith the full resource and a newETagheader if anything has changed.
The client stores whichever ETag it last saw and includes it on the next poll. The wire cost of an "unchanged" poll is a minimal request + empty-body response, regardless of resource size.
The semantics come from the standard HTTP ETag / 304 headers, used in this pattern as a delta channel rather than a browser cache.
Canonical instance (internal control plane)¶
Route Server serves Eskip
routing tables to all
Skipper pods in a Zalando Kubernetes
cluster (Source:
sources/2025-02-16-zalando-scaling-beyond-limits-harnessing-route-server-for-a-stable-cluster).
Each Skipper polls routesrv with its current ETag; when the
routing table is unchanged (the common case — the table only
changes when someone applies a new Ingress or RouteGroup),
routesrv replies 304 and a 20k-route payload is not sent.
Only on change does any Skipper see a 200 OK with a full
Eskip payload, which it loads and stores along with the new
ETag.
Why it works at scale¶
The data plane has N clients pinging the control plane at
interval Δ. The full-payload cost is O(payload_size) per
poll; the ETag-matched cost is O(1) per poll. At Zalando's
numbers (300 Skippers × 3-second interval = 100 rps) the
control plane serves 100 rps of cheap 304s steady-state,
punctuated by brief bursts of full payloads when
Ingress/RouteGroup churn. Throughput planning is done on
the 304-floor, not the payload-ceiling.
Properties¶
- Availability-compatible — a client that can't reach the server simply keeps its last cached copy. Pairs naturally with concepts/last-known-good-routing-table.
- Cheap fan-out — the server's per-client work is a hash-compare + 304. Scales to the hundreds or thousands of clients seen in proxy meshes.
- Interval is a freshness-budget knob — concepts/polling-interval-as-freshness-budget. Shorter interval = tighter freshness, more (cheap) polls.
- ETag granularity is an implementation choice — one per resource vs. one per whole table. A single table-wide ETag (Zalando's choice) means any single route change triggers a full-payload fetch by all clients; per-route ETags would narrow that but complicate the server.
Contrast with push-based protocols¶
Push streams (server-sent events, gRPC streaming, Kubernetes watch, Envoy xDS) avoid the client-side polling loop and can deliver change events with lower latency. Trade-offs:
- Connection state per client — every client holds an
open stream; server process memory and file descriptors
grow with
N. ETag polling holds no per-client state on the server. - Change-event fan-out — a shared change hitting every client at once is thundering herd–shaped for both, but ETag polling is self-jittered by client clocks starting at different moments.
- Freshness — push wins on median propagation, ETag polling's floor is the interval.
Zalando's Route Server explicitly chose HTTP + ETag over informers / streams for the simplicity and the absence of per-client server state (Source: sources/2025-02-16-zalando-scaling-beyond-limits-harnessing-route-server-for-a-stable-cluster).