Redis Caching Strategies That Saved Us 200ms Per Request
At Priority IDC, every millisecond counts in financial transactions. When we analyzed our wallet service, balance lookups were hitting the database on every request — averaging 250ms per query. After implementing Redis caching, we brought that down to 40ms.
The Challenge
Our wallet service handles:
- Balance checks before every transaction
- Real-time balance display on the app
- Concurrent reads during high-traffic periods
The database was becoming a bottleneck, especially during peak hours.
Cache-Aside Pattern (Lazy Loading)
This is our primary pattern for balance reads:
public BigDecimal getBalance(String walletId) {
String cached = redisTemplate.opsForValue()
.get("balance:" + walletId);
if (cached != null) {
return new BigDecimal(cached);
}
BigDecimal balance = walletRepository
.findBalanceByWalletId(walletId);
redisTemplate.opsForValue().set(
"balance:" + walletId,
balance.toString(),
Duration.ofMinutes(5)
);
return balance;
}
Write-Through for Transactions
When a transaction modifies a balance, we update cache immediately:
- Update database (source of truth)
- Update Redis cache
- If cache update fails, invalidate the key
Lessons Learned
- TTL is your safety net — even with write-through, set expiration times
- Use Redis transactions for atomic read-modify-write operations
- Monitor cache hit rates — we maintain 95%+ hit rate
- Plan for cache failures — the system must work (slower) without Redis