The Mechanics
the CLIENT does the work:
1. fetch instance list from registry (cached locally)
2. pick one: client-side load balancing policy
(round-robin, least-request, zone-aware, weighted)
3. call DIRECTLY — no intermediate hop
4. on failure: mark bad, retry ANOTHER instance, refresh list
[caller]──►[registry: orders = {ip1, ip2, ip3}]
│ cached ✓
└────direct────►[ip2] ← no proxy in between
netflix OSS made this famous (ribbon/eureka era);
grpc's rich client-LB continues the lineage.
Why Choose It
□ NO EXTRA HOP: one fewer network leg per call;
latency + infra cost drop
□ SMART POLICIES CLIENT-SIDE:
- zone-affinity (call same-AZ instances first)
- retry-on-ANOTHER-instance instantly (proxy can't know
which sibling to retry as well as the caller)
- outlier ejection from observed behavior
□ FEWER INFRA COMPONENTS: no LB fleet per service-pair
□ CLIENT SEES FAILURES FIRSTHAND → better decisions
The Costs You Sign Up For
- CLIENT COMPLEXITY in EVERY language/framework you run:
registry lookup, caching, balancing, retries, circuit
breaking — reimplemented or library-mandated everywhere
- LIBRARY LOCK-IN-ish: polyglot estates struggle keeping
behavior consistent across java/go/python clients
- UPGRADE TAXIONOMY: fixing a load-balancing bug =
redeploying every calling service (vs one proxy layer)
- REGISTRY COUPLING: every client needs registry access
(cache-last-known-good mitigates; still surface area)
these costs are WHY sidecar/proxy patterns ate this space:
move the smarts OUT of app code into infrastructure.
When It Still Wins
| Scenario | Fit |
|---|---|
| Homogeneous stack, one language | library story coherent |
| Latency-critical internal mesh | hop elimination matters |
| gRPC-native services | built-in client LB excellent |
| Simple estate (few services) | proxy layers overkill |
honest modern framing: raw client-side discovery is
increasingly wrapped BY infrastructure anyway —
xDS-controlled clients (envoy's model) keep the
direct-call property while centralizing POLICY.
the pattern evolved rather than died.
Interview Framing
“Compare discovery approaches for a 50-service Java shop” scored shape: mechanics drawn (registry→cache→direct-call), advantages quantified (hop removal, instant cross-instance retry), costs emphasized (per-language duplication, upgrade sprawl), verdict reasoning for THIS scenario (homogeneous → viable; polyglot → prefer proxy/sidecar). The pattern-comparison questions reward knowing WHERE each approach died in production, not just textbook pros/cons.
Premium Content
Unlock Client-Side Discovery and all premium lessons with a subscription.
All premium lessons
Ad-free experience
Priority support
From ₹199.99/year — See plans