Chapter 9: Caching Strategies
Chapter 9 of 15
Chapter 9: Caching Strategies
9.1 Caching Layers
Caching stores frequently accessed data in fast storage to improve performance. Multiple caching layers work together to optimize application speed.
Browser Caching:
- Stores static assets (CSS, JS, images) in browser
- Reduces server requests
- Controlled by Cache-Control headers
- Fastest access but limited to user's browser
// Cache-Control headers
Cache-Control: public, max-age=31536000 // Cache for 1 year
Cache-Control: no-cache // Revalidate each time
Cache-Control: no-store // Don't cache
CDN Caching:
- Content Delivery Network caches content at edge locations
- Serves content from nearest location
- Reduces latency globally
- Good for static assets and API responses
Application Caching:
- In-memory cache (Redis, Memcached)
- Stores computed results and database queries
- Very fast access
- Shared across application instances
// Redis caching example
const redis = require('redis');
const client = redis.createClient();
// Cache data
await client.setex('user:123', 3600, JSON.stringify(userData));
// Retrieve from cache
const cached = await client.get('user:123');
if (cached) {
return JSON.parse(cached);
}
// Otherwise fetch from database
Database Caching:
- Query result caching
- Reduces database load
- Faster repeated queries
- Can be at database level or application level
9.2 Cache Invalidation
Cache invalidation ensures cached data stays current. Choose strategies based on data characteristics.
Time-Based Expiration (TTL):
- Cache expires after set time
- Simple to implement
- May serve stale data until expiration
- Good for data that changes infrequently
// Set TTL
await cache.set('key', 'value', 'EX', 3600); // Expires in 1 hour
Event-Based Invalidation:
- Invalidate cache when data changes
- Ensures fresh data
- More complex to implement
- Requires tracking data changes
// Invalidate on update
async function updateUser(id, data) {
await db.update('users', id, data);
await cache.del(`user:${id}`); // Remove from cache
}
Cache-Aside Pattern:
- Application checks cache first
- If miss, fetch from database and cache
- Application manages cache
- Common pattern
Write-Through Pattern:
- Write to cache and database simultaneously
- Cache always up to date
- Slower writes
- Good for critical data
9.3 Caching Best Practices
Follow best practices for effective caching.
- Cache expensive operations (database queries, API calls)
- Use appropriate TTL values
- Implement cache warming for critical data
- Monitor cache hit rates
- Handle cache failures gracefully
- Use cache keys consistently
- Consider cache size limits