Java
Spring Cloud Gateway
Redis
Session Management
Microservices

Working example of Spring Cloud Gateway with Redis session management?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Spring Cloud Gateway can sit in front of downstream services while Redis holds shared session state, which is useful when requests may be routed across multiple instances. The key is to combine reactive gateway routing with Spring Session backed by Redis so session data survives beyond one JVM instance and can be reused on later requests.

What the Pieces Do

In this setup:

  • Spring Cloud Gateway handles routing and filters
  • Spring Session stores WebSession data in Redis
  • Redis acts as the shared backing store for session attributes

This is different from using the gateway as a stateless token-only edge. If you choose session management, the gateway needs to persist and reload session state consistently.

Minimal Dependency Set

A typical Maven setup includes the gateway starter, Redis support, and Spring Session for Redis:

xml
1<dependencies>
2  <dependency>
3    <groupId>org.springframework.cloud</groupId>
4    <artifactId>spring-cloud-starter-gateway</artifactId>
5  </dependency>
6  <dependency>
7    <groupId>org.springframework.boot</groupId>
8    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
9  </dependency>
10  <dependency>
11    <groupId>org.springframework.session</groupId>
12    <artifactId>spring-session-data-redis</artifactId>
13  </dependency>
14</dependencies>

The important part is using the reactive Redis stack, because Spring Cloud Gateway is built on Spring WebFlux rather than the traditional servlet model.

Application Configuration

A small application.yml can define both the Redis connection and the gateway route.

yaml
1spring:
2  data:
3    redis:
4      host: localhost
5      port: 6379
6  session:
7    store-type: redis
8  cloud:
9    gateway:
10      routes:
11        - id: demo-service
12          uri: http://localhost:8081
13          predicates:
14            - Path=/api/**
15          filters:
16            - StripPrefix=1
17            - SaveSession
18server:
19  port: 8080

SaveSession matters when the session has been modified and you want the gateway to persist it before forwarding the request onward.

A Simple Gateway Application

A minimal Spring Boot entry point is ordinary:

java
1import org.springframework.boot.SpringApplication;
2import org.springframework.boot.autoconfigure.SpringBootApplication;
3
4@SpringBootApplication
5public class GatewayApplication {
6    public static void main(String[] args) {
7        SpringApplication.run(GatewayApplication.class, args);
8    }
9}

The interesting behavior comes from how requests interact with the session.

Writing Session Data Through the Gateway

A small controller inside the gateway can demonstrate that the session is really stored in Redis.

java
1import org.springframework.web.bind.annotation.GetMapping;
2import org.springframework.web.bind.annotation.RestController;
3import org.springframework.web.server.WebSession;
4import reactor.core.publisher.Mono;
5
6import java.util.HashMap;
7import java.util.Map;
8
9@RestController
10public class SessionController {
11
12    @GetMapping("/session")
13    public Mono<Map<String, Object>> session(WebSession session) {
14        Integer counter = session.getAttributeOrDefault("counter", 0);
15        counter++;
16        session.getAttributes().put("counter", counter);
17
18        Map<String, Object> response = new HashMap<>();
19        response.put("sessionId", session.getId());
20        response.put("counter", counter);
21        return Mono.just(response);
22    }
23}

Hit /session repeatedly and the counter should continue increasing for the same client session. That is the easiest proof that state is surviving outside process memory.

A Downstream Service Example

You can route authenticated or session-aware traffic to a downstream service. Here is a tiny backend service on port 8081:

java
1import org.springframework.web.bind.annotation.GetMapping;
2import org.springframework.web.bind.annotation.RestController;
3import reactor.core.publisher.Mono;
4
5@RestController
6public class DownstreamController {
7
8    @GetMapping("/hello")
9    public Mono<String> hello() {
10        return Mono.just("hello from downstream service");
11    }
12}

With the gateway route shown earlier, a call to /api/hello on port 8080 is forwarded to the backend.

In a real application, the gateway often combines routing with Spring Security and session-backed authentication state. Redis helps because multiple gateway instances can share the same session store.

Running Redis Locally

For local testing, a disposable Redis container is usually enough:

bash
docker run --name gateway-redis -p 6379:6379 redis:7

Once Redis is running, start the gateway and call the session endpoint:

bash
curl -c cookies.txt -b cookies.txt http://localhost:8080/session
curl -c cookies.txt -b cookies.txt http://localhost:8080/session

Reusing the same cookie jar should show the session counter increasing.

Common Pitfalls

The most common mistake is mixing servlet-style session assumptions into a reactive gateway project and then using the wrong Redis or session dependencies. Another is forgetting the SaveSession filter when the gateway mutates session state before forwarding. Teams also often test with one gateway instance only and miss the real point of Redis-backed sessions, which is shared state across instances. A final issue is treating session management and stateless token-based designs as interchangeable even though they produce very different gateway behavior and scaling tradeoffs.

Summary

  • Spring Cloud Gateway can use Spring Session with Redis to persist shared reactive session state.
  • Use reactive Redis dependencies, not the servlet-centric stack.
  • Configure Redis, gateway routes, and SaveSession explicitly.
  • A simple WebSession controller is an easy way to verify persistence.
  • Redis-backed sessions are most valuable when gateway instances need shared session state rather than purely stateless routing.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.