What is the difference between client-side and server-side discovery
least-connections, by availability zone). With server-side discovery this decision is made by the LB, and the client cannot influence it.
Junior Level
Client-side discovery:
Service A asks the Registry itself and calls Service B
Service A -> Registry: "Where is service B?" -> 10.0.0.5:8080 -> call
Server-side discovery:
Service A calls the Load Balancer, and the LB finds Service B
Service A -> Load Balancer -> Registry -> Service B
Difference: who makes the request to the Registry — the client or the server (LB).
Middle Level
Client-side
// Service A looks up service B itself
ServiceRegistry registry = new ConsulRegistry("consul:8500");
ServiceInstance instance = registry.getInstance("service-b");
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.build();
HttpResponse<String> response = client.send(
HttpRequest.newBuilder(URI.create("http://" + instance.getAddress() + "/api"))
.GET().build(),
BodyHandlers.ofString()
);
Pros:
- More control: the service itself decides which instance to choose (round-robin, least-connections, by availability zone). With server-side discovery this decision is made by the LB, and the client cannot influence it.
- No additional hop through LB
Cons:
- Need to implement discovery logic in each service
- Dependency on Registry SDK
Server-side
Service A -> Load Balancer (Nginx/HAProxy) -> Service B
# Nginx config
# In production, Nginx Plus or consul-template dynamically update upstreams.
# Static IPs — simplification for the example.
upstream service_b {
server 10.0.0.5:8080;
server 10.0.0.6:8080;
}
Pros:
- Simpler for clients
- LB handles discovery and balancing
Cons:
- Additional hop (latency)
- LB — single point of failure
Common mistakes
- Client-side: caching without TTL:
Service A cached service B's IP Service B moved to a new IP Service A hits the old IP
Senior Level
Architectural Trade-offs
| Client-side | Server-side |
|---|---|
| No single point of failure | LB can go down |
| More complex to implement | Simpler |
| Less latency | +1 hop |
| Flexibility (retry, circuit breaker) | Less control |
Production Experience
Kubernetes (server-side):
K8s Services -> kube-proxy -> Endpoints
Service A -> my-service:8080 -> kube-proxy -> Pod B
Netflix Ribbon (client-side): ⚠️ Netflix Ribbon is deprecated (in maintenance mode since 2018). In modern projects, use Spring Cloud LoadBalancer or K8s Service.
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// Ribbon handles discovery + load balancing
restTemplate.getForObject("http://service-b/api", String.class);
Best Practices
✅ Client-side: caching with TTL
✅ Server-side: multiple LBs for HA
✅ Health checks in both cases
✅ Fallback when Registry is unavailable
❌ Without caching (too many Registry calls)
❌ Without fallback when LB is unavailable
Interview Cheat Sheet
Must know:
- Client-side: service asks the Registry itself and chooses the instance (round-robin, least-connections)
- Server-side: LB handles discovery and balancing (Nginx, K8s Service)
- Client-side: no extra hop, but need to implement logic in each service
- Server-side: simpler for clients, but +1 hop and LB is a potential SPOF
- Netflix Ribbon is deprecated (maintenance mode since 2018) — use Spring Cloud LoadBalancer
- Client-side caching is MANDATORY with TTL, otherwise stale IP
- K8s uses server-side: kube-proxy -> Endpoints
Common follow-up questions:
- When to choose client-side? Need flexibility (retry, circuit breaker), minimal latency.
- When to choose server-side? Simpler, when the team doesn’t want to write discovery logic.
- What happens without TTL in cache? Service moved to a new IP — client hits the old one.
- What type is K8s? Server-side: Service -> DNS -> kube-proxy -> Pod.
Red flags (DO NOT say):
- “Netflix Ribbon is the best choice” — deprecated, use Spring Cloud LoadBalancer
- “Caching is not needed, Registry is fast” — unnecessary load on Registry with every call
- “Server-side is always better” — depends on flexibility requirements
- “LB never goes down” — need HA (multiple LBs)
Related topics:
- [[7. What is Service Discovery and why is it needed]]
- [[9. What is API Gateway and what problems does it solve]]
- [[12. How to implement horizontal scaling of microservices]]
- [[26. What tools are used for microservice orchestration]]
- [[16. What is the difference between synchronous and asynchronous communication]]