Back to Articles
"Backend Development"Jul 2, 2024"8 min read"

"Redis Beyond Caching: 10 Essential Use Cases"

"A concise cheat sheet of 10 Redis use cases using Spring Data Redis (StringRedisTemplate) with practical examples and architecture diagrams."

#Redis#Spring Boot#Distributed Systems#Java#Caching

Redis is often pigeonholed as just a caching layer, but it's a versatile data structure server that can solve many distributed systems problems. Here are 10 practical use cases with Spring Data Redis.

1. Distributed Rate Limiting

Scenario: Limit "Forgot Password" to 3 tries/hour.

String key = "rate:" + userId;
redis.opsForValue().setIfAbsent(key, "1", Duration.ofHours(1));
Long count = redis.opsForValue().increment(key);
if (count > 3) throw new RateLimitException();

2. Distributed Locks

Scenario: Prevent double-booking the last airline seat.

String uuid = UUID.randomUUID().toString();
Boolean locked = redis.opsForValue()
    .setIfAbsent("lock:seat:" + id, uuid, Duration.ofSeconds(10));

if (Boolean.TRUE.equals(locked)) {
    try { 
        bookSeat(); 
    } finally { 
        // Lua script to delete lock ONLY if value == uuid
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                       "return redis.call('del', KEYS[1]) else return 0 end";
        redis.execute(new DefaultRedisScript<>(script, Long.class), 
                     Collections.singletonList("lock:seat:" + id), uuid);
    }
}

3. Job Queues

Scenario: Async PDF invoice generation.

// Producer
redis.opsForList().rightPush("queue:invoices", orderId);

// Consumer (Blocking)
String job = redis.opsForList()
    .leftPop("queue:invoices", 30, TimeUnit.SECONDS);

4. Real-Time Leaderboards

Scenario: Strava weekly step challenge rankings.

redis.opsForZSet().incrementScore("lb:steps", userId, stepsAdded);
Set<TypedTuple<String>> top10 = redis.opsForZSet()
    .reverseRangeWithScores("lb:steps", 0, 9);
Long rank = redis.opsForZSet().reverseRank("lb:steps", userId);

5. Session Storage

Scenario: Share user sessions across multiple API pods.

redis.opsForValue().set("sess:" + tokenId, userJson, Duration.ofHours(8));
String user = redis.opsForValue().get("sess:" + tokenId);

6. Pub/Sub Messaging

Scenario: Uber "Driver is arriving" WebSocket push.

// Publisher
redis.convertAndSend("channel:ride:" + riderId, "Driver arriving");

// Subscriber (implements MessageListener)
public void onMessage(Message msg, byte[] p) { 
    pushToWebSocket(new String(msg.getBody())); 
}

7. Feature Flags

Scenario: Instantly disable crypto trading without deploying code.

// Admin Toggle
redis.opsForHash().put("flags", "crypto_trade", String.valueOf(false));

// API Check
boolean isEnabled = Boolean.parseBoolean(
    redis.opsForHash().get("flags", "crypto_trade").toString()
);

8. Health Monitoring

Scenario: PagerDuty alert if payment declines spike.

long bucket = System.currentTimeMillis() / 120_000; // 2-min bucket
String key = "mon:declines:" + bucket;
Long count = redis.opsForValue().increment(key);
if (count == 1) redis.expire(key, Duration.ofMinutes(2));
if (count == 50) triggerAlert();

9. Geospatial Search

Scenario: DoorDash finding 5 nearest drivers.

redis.opsForGeo().add("geo:drivers", new Point(lon, lat), driverId);
Circle circle = new Circle(
    new Point(restLon, restLat), 
    new Distance(3, Metrics.KILOMETERS)
);
GeoResults<GeoLocation<String>> nearest = redis.opsForGeo()
    .radius("geo:drivers", circle, args.limit(5));

10. Event Sourcing (Streams)

Scenario: Immutable banking transaction audit log.

Map<String, String> event = Map.of("account", "123", "amount", "50.00");
redis.opsForStream().add("stream:ledger", event); // Auto-generates ID

List<MapRecord<String, Object, Object>> history = redis.opsForStream()
    .range("stream:ledger", Range.unbounded());

Key Takeaways

  • Atomic operations: Redis provides atomic primitives for distributed coordination
  • Data structures: Choose the right structure (String, Hash, List, Set, ZSet, Geo, Stream)
  • TTL: Always set expiration to prevent memory leaks
  • Performance: In-memory operations make Redis ideal for low-latency use cases
  • Scalability: Single Redis instance can be replaced with Redis Cluster for horizontal scaling

Redis is more than a cache—it's a Swiss Army knife for distributed systems challenges.