Mastering Redis Caching & Rate Limiting in Node.js Microservices
In high-throughput microservice architectures, in-memory caching with Redis is crucial for relieving database bottlenecks and reaching sub-millisecond API responses.
1. The Cache-Aside Strategy
With the Cache-Aside pattern, the backend first queries Redis. If the key exists (cache hit), data returns immediately. On a cache miss, data is fetched from SQL/NoSQL, populated into Redis with a TTL, and returned to the client.
const getCachedData = async (key, fetcher, ttlInSeconds = 3600) => {
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const freshData = await fetcher();
await redis.setex(key, ttlInSeconds, JSON.stringify(freshData));
return freshData;
};2. Sliding-Window Rate Limiting
Protecting public endpoints from DDoS and abusive scraping requires robust rate limiters. Redis sorted sets (ZSET) provide a precise sliding-window rate limiting mechanism.
By storing request timestamps in Redis ZSETs, you can count requests within any dynamic time window without fixed boundary spikes.
Preventing Cache Stampedes
Use distributed locks (Redlock algorithm) when re-populating expensive cache items so only a single worker queries the database on cache expiration.