Home/Learn/Microservices/Client-Side Load Balancing

Client-Side Load Balancing

Intermediate
Discovery & Gateway

Spring Cloud LoadBalancer selects a service instance from the registry using round-robin or custom strategies, allowing callers to balance traffic without a dedicated proxy.

Overview

Client-side load balancing moves the balancing logic into the calling service rather than relying on a dedicated proxy. The client fetches a list of available instances from the service registry (Eureka, Consul) and applies a selection algorithm before making the HTTP call. Spring Cloud LoadBalancer (SCL) replaced the deprecated Netflix Ribbon in Spring Cloud 2020+. It integrates with Spring's @LoadBalanced RestTemplate and WebClient, and plugs into Spring Cloud Gateway for gateway-level balancing.

Spring Cloud LoadBalancer with RestTemplate

Annotate a RestTemplate or WebClient.Builder bean with @LoadBalanced. Spring replaces the logical service name in the URL with a real host:port chosen by SCL from the registry.

Java — @LoadBalanced RestTemplate
// Configuration
@Configuration
public class WebConfig {
    @Bean
    @LoadBalanced   // enables client-side LB on this RestTemplate
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

// Usage — use logical service name, not a real host
@Service
public class OrderClient {
    private final RestTemplate restTemplate;

    public ProductDTO getProduct(Long id) {
        // "product-service" is the service ID in Eureka/Consul
        return restTemplate.getForObject(
            "http://product-service/api/products/{id}",
            ProductDTO.class, id);
        // SCL resolves → e.g. http://10.0.1.15:8081/api/products/42
    }
}

WebClient with Reactive Load Balancing

For reactive stacks inject @LoadBalanced WebClient.Builder. Spring Cloud LoadBalancer integrates seamlessly with Spring WebFlux.

Java — @LoadBalanced WebClient (reactive)
@Configuration
public class WebClientConfig {
    @Bean
    @LoadBalanced
    public WebClient.Builder loadBalancedWebClientBuilder() {
        return WebClient.builder();
    }
}

@Service
public class InventoryClient {
    private final WebClient webClient;

    public InventoryClient(WebClient.Builder builder) {
        this.webClient = builder.baseUrl("http://inventory-service").build();
    }

    public Mono<StockDTO> getStock(String sku) {
        return webClient.get()
            .uri("/api/stock/{sku}", sku)
            .retrieve()
            .bodyToMono(StockDTO.class);
    }
}

// application.yml — no extra LB config needed; round-robin is default
spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: false   # explicitly disable Ribbon (Spring Boot 2.x)

Custom Load Balancer Strategy

Implement ReactorServiceInstanceLoadBalancer to apply a custom algorithm (e.g. least-connections, zone-aware, random). Register it via @LoadBalancerClient.

Java — Custom ReactorServiceInstanceLoadBalancer
// Custom random load balancer
public class RandomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    private final ServiceInstanceListSupplier supplier;

    public RandomLoadBalancer(ServiceInstanceListSupplier supplier) {
        this.supplier = supplier;
    }

    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        return supplier.get(request)
            .next()
            .map(instances -> {
                if (instances.isEmpty()) return new EmptyResponse();
                int idx = ThreadLocalRandom.current().nextInt(instances.size());
                return new DefaultResponse(instances.get(idx));
            });
    }
}

// Register for a specific service
@Configuration
@LoadBalancerClient(name = "product-service",
                    configuration = ProductServiceLBConfig.class)
public class ProductServiceLBConfig {
    @Bean
    public ReactorServiceInstanceLoadBalancer randomLB(
            ServiceInstanceListSupplier supplier) {
        return new RandomLoadBalancer(supplier);
    }
}

Key Points to Remember

  • 1Client-side LB fetches instances from the registry and selects one before calling.
  • 2@LoadBalanced on RestTemplate or WebClient.Builder enables SCL automatically.
  • 3Use the logical service name (http://service-id/...) — SCL resolves it to a real address.
  • 4Spring Cloud LoadBalancer replaced Netflix Ribbon in Spring Cloud 2020+.
  • 5Default strategy is round-robin; swap with a custom ReactorServiceInstanceLoadBalancer.
  • 6@LoadBalancerClient scopes a custom strategy to a specific target service.

Interview Questions

Sign in to ask Aria
1

What is the difference between client-side and server-side load balancing?

EasyCognizant
2

How does @LoadBalanced RestTemplate know which instance to pick?

MediumAmazon
3

What replaced Netflix Ribbon in modern Spring Cloud versions?

EasyInfosys
4

How would you implement a zone-aware load balancing strategy?

HardNetflix
5

What happens if no instances are available when SCL tries to choose?

MediumUber

Ask Aria about Client-Side Load Balancing

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…