Caching Strategies
Learn how to implement effective caching strategies at different levels of your application stack to improve performance and reduce server load.
Prerequisites
- Understanding of HTTP caching headers
- Basic knowledge of CDNs
- Familiarity with Redis or similar caching systems
- Experience with Node.js middleware
Caching Overview

Visual representation of multi-layer caching strategy in a web application.
1
Browser Caching
Configure browser caching with proper cache headers:
// Set cache-control headers
app.use((req, res, next) => {
// Static assets
if (req.url.match(/.(jpg|jpeg|png|gif|css|js)$/)) {
res.setHeader('Cache-Control', 'public, max-age=31536000');
} else {
// Dynamic content
res.setHeader('Cache-Control', 'no-cache');
}
next();
});
2
CDN Caching
Implement CDN caching for static assets:
// Configure CDN caching rules
module.exports = {
cdn: {
// Cache static assets for 1 year
'/static/*': {
edge_ttl: 31536000,
browser_ttl: 31536000,
cache_by_default: true
},
// Cache API responses for 1 hour
'/api/*': {
edge_ttl: 3600,
browser_ttl: 0,
cache_by_default: false,
cache_keys: ['cookie', 'host']
}
}
}
3
Application Caching
Set up in-memory caching for application data:
import NodeCache from 'node-cache';
// Initialize cache with TTL of 10 minutes
const cache = new NodeCache({ stdTTL: 600 });
// Cache middleware
const cacheMiddleware = (duration) => {
return (req, res, next) => {
const key = req.originalUrl;
const cachedResponse = cache.get(key);
if (cachedResponse) {
res.send(cachedResponse);
return;
}
res.sendResponse = res.send;
res.send = (body) => {
cache.set(key, body, duration);
res.sendResponse(body);
};
next();
};
};
// Apply to routes
app.get('/api/data', cacheMiddleware(300), (req, res) => {
// Route handler
});
4
Database Caching
Implement database query caching:
import Redis from 'ioredis';
const redis = new Redis();
async function getCachedData(key, fetchFn) {
// Try to get from cache
const cached = await redis.get(key);
if (cached) {
return JSON.parse(cached);
}
// Fetch fresh data
const data = await fetchFn();
// Cache for 1 hour
await redis.setex(key, 3600, JSON.stringify(data));
return data;
}
// Usage example
const users = await getCachedData('users', async () => {
return await db.users.findAll();
});
Best Practices
Cache Invalidation
Strategies for effective cache invalidation:
- Use versioned cache keys
- Implement cache busting
- Set appropriate TTLs
- Monitor cache hit rates
Performance Optimization
Optimize caching for performance:
- Cache at multiple levels
- Use compression
- Implement cache warming
- Monitor memory usage
Security Considerations
Secure your caching implementation:
- Don't cache sensitive data
- Validate cached data
- Use HTTPS for CDN
- Implement access controls
Troubleshooting
Cache Invalidation Issues
Common caching problems:
- Stale cache data
- Cache key conflicts
- Memory leaks
- Race conditions
Performance Problems
Performance-related issues:
- Low cache hit rates
- Slow cache responses
- Cache stampede
- Memory pressure