Weighted routing in Spring Cloud Gateway

Weighted routing in Spring Cloud Gateway is built-in via the Weight Route Predicate. You define multiple routes in the same group, each with a different weight, and Gateway will distribute matching requests proportionally (per group).


1) Add Spring Cloud Gateway (WebFlux) dependency

Maven

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

Spring Cloud Gateway runs on WebFlux/Netty (not traditional servlet containers/WAR).


2) Weighted routing with application.yml (most common)

Example: split /api/** traffic 80/20 between two backends:

spring:
  cloud:
    gateway:
      routes:
        - id: api_v2_80
          uri: http://service-v2:8080
          predicates:
            - Path=/api/**
            - Weight=api-rollout, 80

        - id: api_v1_20
          uri: http://service-v1:8080
          predicates:
            - Path=/api/**
            - Weight=api-rollout, 20

Key rules:

  • Same group name (api-rollout) = they compete with each other.
  • Weights are calculated per group.

3) Weighted routing in Java config (RouteLocator)

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayRoutesConfig {

  @Bean
  public RouteLocator weightedRoutes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("api_v2_80", r -> r
            .path("/api/**")
            .and()
            .weight("api-rollout", 80)
            .uri("http://service-v2:8080"))
        .route("api_v1_20", r -> r
            .path("/api/**")
            .and()
            .weight("api-rollout", 20)
            .uri("http://service-v1:8080"))
        .build();
  }
}

The predicate takes group + weight (int).


Practical tips (so it behaves how you expect)

  • Make sure the “non-weight” predicates match the same traffic (e.g., both have Path=/api/**). If one route matches different traffic, your split will look “off”.
  • Weighted routing is not sticky by default (a single user may bounce between versions). If you need stickiness, combine with a Cookie/Header predicate (e.g., route certain users to v2) instead of pure weight-based randomness.


Leave a Reply

Your email address will not be published. Required fields are marked *

A Backend Engineer who enjoys building scalable systems, clean architectures, and high-performance applications.

About Me

Contact

Copyright: © 2026. All Rights Reserved.