Skip to main content
The Spring Boot Redis Rate Limiter requires a Redis instance to store rate limit counters. This guide shows you how to set up Redis for local development and production.

Prerequisites

The rate limiter uses Spring Data Redis and automatically configures itself when it detects a StringRedisTemplate bean. You need to add the Spring Data Redis dependency to your project:
pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Local development with Docker

The fastest way to run Redis locally is using Docker:
docker run -d \
  --name redis-ratelimiter \
  -p 6379:6379 \
  redis:7.2-alpine
Then configure your application to connect to it:
spring.data.redis.host=localhost
spring.data.redis.port=6379

Docker Compose

For a more complete local setup, use Docker Compose:
docker-compose.yml
version: '3.8'

services:
  redis:
    image: redis:7.2-alpine
    container_name: redis-ratelimiter
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    command: redis-server --appendonly yes
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

  app:
    build: .
    depends_on:
      redis:
        condition: service_healthy
    environment:
      - SPRING_DATA_REDIS_HOST=redis
      - SPRING_DATA_REDIS_PORT=6379
    ports:
      - "8080:8080"

volumes:
  redis-data:
Start the services:
docker-compose up -d
When running in Docker Compose, set the Redis host to the service name (redis) instead of localhost.

Spring Data Redis configuration

Basic connection

# Redis server connection
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.password=
spring.data.redis.database=0

Connection pool (Lettuce)

The rate limiter uses Lettuce (the default Spring Data Redis client). Configure connection pooling for better performance:
# Lettuce connection pool
spring.data.redis.lettuce.pool.enabled=true
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=2
spring.data.redis.lettuce.pool.max-wait=-1ms

# Connection timeout
spring.data.redis.timeout=2000ms
Connection pooling requires commons-pool2 on the classpath. Add it as a dependency:
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-pool2</artifactId>
</dependency>

Redis Cluster

For high availability, configure Redis Cluster:
spring.data.redis.cluster.nodes=node1:6379,node2:6379,node3:6379
spring.data.redis.cluster.max-redirects=3
spring.data.redis.password=your-password

Redis Sentinel

For automatic failover, configure Redis Sentinel:
spring.data.redis.sentinel.master=mymaster
spring.data.redis.sentinel.nodes=sentinel1:26379,sentinel2:26379,sentinel3:26379
spring.data.redis.password=your-password

Production configuration

For production environments, use a robust configuration with connection pooling, timeouts, and SSL:
# Redis connection
spring.data.redis.host=redis.production.example.com
spring.data.redis.port=6380
spring.data.redis.password=${REDIS_PASSWORD}
spring.data.redis.database=0
spring.data.redis.ssl.enabled=true

# Connection pool
spring.data.redis.lettuce.pool.enabled=true
spring.data.redis.lettuce.pool.max-active=16
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=4
spring.data.redis.lettuce.pool.max-wait=5000ms

# Timeouts
spring.data.redis.timeout=3000ms
spring.data.redis.connect-timeout=3000ms

# Rate limiter configuration
ratelimiter.redis-key-prefix=prod:api:ratelimit
ratelimiter.fail-open=false
ratelimiter.metrics-enabled=true
Always use environment variables or secrets management for production credentials. Never commit passwords to version control.

Testing the connection

You can verify your Redis connection is working by checking the Spring Boot actuator health endpoint:
curl http://localhost:8080/actuator/health/redis
Or by running a simple test:
RedisConnectionTest.java
@SpringBootTest
class RedisConnectionTest {

  @Autowired
  private StringRedisTemplate redisTemplate;

  @Test
  void redisConnectionWorks() {
    redisTemplate.opsForValue().set("test-key", "test-value");
    String value = redisTemplate.opsForValue().get("test-key");
    assertThat(value).isEqualTo("test-value");
  }
}

Redis key structure

The rate limiter stores counters in Redis using this key pattern:
{redis-key-prefix}:{key}:{windowStartMillis}
For example, with the default prefix and a key of user:123:
ratelimiter:user:123:1700000000000
Keys are automatically expired using Redis TTL based on the rate limit window duration plus a 1-second safety buffer.

Monitoring Redis

Monitor your Redis instance to ensure the rate limiter is performing well:
# Check current keys
redis-cli --scan --pattern "ratelimiter:*"

# Monitor commands in real-time
redis-cli MONITOR

# Check memory usage
redis-cli INFO memory

# Check connection stats
redis-cli INFO clients