When a 100ms Redis Cache Fetch Suddenly Took 137 Seconds: A Production Postmortem

When a 100ms Redis Cache Fetch Suddenly Took 137 Seconds: A Production Postmortem

Introduction

Redis is often considered one of the fastest components in a modern microservice architecture. Since it’s an in-memory data store, developers generally expect cache retrieval times to be measured in milliseconds, not seconds.

Recently, we encountered a production incident where Redis cache latency increased dramatically, with a cache fetch that normally completed in 100-800 milliseconds suddenly taking 137 seconds.

The result?

  • Increased API response times
  • Thread pool exhaustion
  • Kafka consumer lag
  • Cascading delays across more than one microservices
  • Multiple production alerts and SLA breaches

The System Architecture

The application consists of multiple microservices communicating synchronously through REST APIs and asynchronously through Kafka.

Client

  ↓

API Gateway

  ↓

Service A

  ↓

Redis

  ↓

Service B

  ↓

Service C

  ↓

Service D

  ↓

Kafka Consumers

Several downstream services depended directly or indirectly on the response from Service A.

The Incident

Under normal conditions:

Redis cache fetch latency:  100ms – 800ms

During the incident:

Redis cache fetch latency:  137 seconds

Immediately after this:

  • API latency increased dramatically.
  • Request queues started growing.
  • Thread pools became saturated.
  • Kafka consumers started lagging.
  • Dependent services began timing out.
  • Alerts were triggered across multiple services.

At first glance, it appeared to be a Redis issue.

However, the investigation revealed that the problem was much larger than Redis itself.

Why Even 500ms Is High for Redis

Redis is an in-memory database.

Typical response times are:

EnvironmentExpected Latency
Same Server<1ms
Same VPC1-5ms
Different Availability Zone5-20ms
Cross Region20-50ms

Understanding the Cascading Failure

The biggest problem wasn’t the slow Redis call itself.

The real problem was that every downstream service waited for the response.

Service A

Service B waits

Service C waits

Service D waits

Eventually:

Blocked Threads

Connection Pool Exhaustion

Request Queue Build-up

Increased Latency

Timeouts

System-wide Alarms

This phenomenon is called Cascading Failure

One slow dependency slowly degrades the entire distributed system.

Possible Root Causes

1. Redis Connection Pool Exhaustion

One of the most common reasons for long Redis response times.

Suppose:

spring:

 data:

   redis:

     lettuce:

       pool:

         max-active: 8

If hundreds of requests simultaneously attempt to access Redis, they start waiting for available connections.

The wait time can quickly increase from milliseconds to several minutes.

Symptoms

  • Increased request latency
  • High thread count
  • Low Redis CPU usage
  • High connection wait time

2. Cache Stampede

A cache stampede occurs when thousands of requests attempt to load the same key simultaneously.

10,000 Requests

       ↓

Same Cache Key

       ↓

Heavy Contention

The Redis server becomes overloaded, and response times increase significantly.

Prevention

  • Cache warming
  • Request coalescing
  • Distributed locks
  • Stale cache strategy

3. Huge Cached Objects

Sometimes applications cache very large objects.

Example:

UserProfile

ProductCatalog

MediaMetadata

Large payloads increase:

  • Serialization time
  • Deserialization time
  • Network transfer time
  • Memory consumption

4. Network Problems

Sometimes Redis is perfectly healthy.

The delay comes from:

  • DNS resolution issues
  • Packet loss
  • Cross-region communication
  • Kubernetes networking problems
  • Load balancer issues

Production Investigation Checklist

During incidents like this, investigate the following metrics immediately:

Redis Metrics

  • CPU utilization
  • Memory utilization
  • Connection count
  • Slow queries
  • Network throughput
  • Cache hit ratio

Application Metrics

  • Thread pool utilization
  • Connection pool utilization
  • GC pauses
  • Heap usage
  • Request queue size

Kafka Metrics

  • Consumer lag
  • Processing time
  • Message backlog

Immediate Mitigation

1. Fail Fast

Never allow Redis requests to wait for minutes.

spring:

 data:

   redis: 

      timeout: 2s

2. Use Circuit Breakers

@CircuitBreaker(name = “redis”)

If Redis becomes slow:

  • Stop sending requests.
  • Return fallback responses.
  • Protect downstream services.

3. Bulkhead Isolation

@Bulkhead(name = “redis”)

Redis failures should not consume all application threads.

4. Fallback Cache

return staleCachedData;

Returning slightly old data is often better than bringing down the platform.

5. Monitor Everything

Important alerts:

  • Redis latency > 50ms
  • Connection pool usage > 80%
  • Thread pool utilization > 80%
  • Kafka consumer lag
  • Slow query count

Conclusion

The biggest lesson from this incident is that in distributed systems, a dependency becoming slow can be more dangerous than a dependency completely failing.

A Redis cache fetch that normally took 100-800 milliseconds suddenly taking 137 seconds was not just a Redis problem, it became a platform-wide problem. The delay propagated across more than one microservices, leading to thread pool exhaustion, increased Kafka consumer lag, service timeouts, and multiple production alerts.

The incident highlighted an important engineering principle: every external dependency, no matter how reliable, can eventually become slow or unavailable. Systems must therefore be designed with resilience in mind.

Implementing proper timeouts, circuit breakers, bulkhead isolation, fallback mechanisms, and comprehensive monitoring ensures that a single slow component cannot bring down an entire ecosystem.

The goal of a resilient microservice architecture is not to prevent failures completely, failures are inevitable. The goal is to contain them, isolate them, and ensure that one service’s problem never becomes everyone’s problem.

Author

  • Pooja Jayan is a Software Developer with 3.5 years of experience in Java backend development. Specializes in building scalable, high-performance applications using Java, Spring Boot, REST APIs, and microservices.

    She has hands-on experience designing and developing backend services, working with relational and NoSQL databases, and collaborating in Agile development environments. Passionate about writing clean, maintainable code, she enjoys solving complex technical challenges and building efficient, reliable software solutions.

Contact us