| name | implement-caching |
| description | Implement comprehensive multi-level API caching strategies with Redis, CDN,...
|
| shortcut | cach |
| category | api |
| difficulty | intermediate |
| estimated_time | 2-3 hours |
| version | 2.0.0 |
Implement API Caching
Creates comprehensive multi-level caching strategies to dramatically improve API performance, reduce database load, and enhance user experience. Implements Redis for server-side caching, CDN integration for edge caching, and proper HTTP cache headers for client-side optimization.
When to Use
Use this command when:
- API response times exceed acceptable thresholds (>200ms)
- Database queries are repetitive and expensive
- Static or semi-static content dominates API responses
- High traffic causes server strain and increased costs
- Geographic distribution requires edge caching
- Rate limiting needs efficient request counting
- Session data requires fast access across servers
Do NOT use this command for:
- Real-time data that changes every request
- User-specific sensitive data (without proper cache isolation)
- APIs with complex invalidation dependencies
- Small-scale applications where caching adds unnecessary complexity
Prerequisites
Before running this command, ensure:
Process
Step 1: Analyze API Patterns
The command examines your API to determine optimal caching strategies:
- Identifies read-heavy endpoints suitable for caching
- Categorizes data by volatility (static, semi-dynamic, dynamic)
- Analyzes request patterns and frequency
- Determines appropriate cache TTL values
- Maps data dependencies for invalidation
Step 2: Implement Server-Side Caching
Sets up Redis-based caching with intelligent patterns:
- Cache-aside pattern for on-demand caching
- Write-through for immediate cache updates
- Write-behind for asynchronous cache population
- Distributed caching for horizontal scaling
- Cache warming for critical data
Step 3: Configure HTTP Cache Headers
Implements proper HTTP caching directives:
- Cache-Control headers with appropriate max-age
- ETag generation for conditional requests
- Vary headers for content negotiation
- Surrogate-Control for CDN-specific behavior
- Stale-while-revalidate for improved perceived performance
Step 4: Integrate CDN Caching
Configures edge caching for global distribution:
- Cache rules based on URL patterns
- Geographic cache distribution
- Cache purging API integration
- Origin shield configuration
- Custom cache keys for variants
Step 5: Implement Cache Invalidation
Creates sophisticated invalidation strategies:
- Tag-based invalidation for related content
- Event-driven cache clearing
- Time-based expiration with jitter
- Cascade invalidation for dependent data
- Soft purging with grace periods
Output Format
The command generates a complete caching implementation:
api-caching/
├── src/
│ ├── cache/
│ │ ├── redis-client.js
│ │ ├── cache-middleware.js
│ │ ├── cache-strategies.js
│ │ └── invalidation-service.js
│ ├── middleware/
│ │ ├── http-cache-headers.js
│ │ └── cdn-integration.js
│ └── utils/
│ ├── cache-key-generator.js
│ └── cache-metrics.js
├── config/
│ ├── cache-config.json
│ ├── redis.config.js
│ └── cdn-rules.json
├── tests/
│ └── cache.test.js
└── docs/
└── caching-strategy.md
Examples
Example 1: E-commerce Product API with Redis
Scenario: High-traffic product catalog requiring sub-100ms response times
Generated Redis Implementation:
import Redis from 'ioredis';
import { promisify } from 'util';
class CacheManager {
constructor() {
this.client = new Redis({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD,
retryStrategy: (times) => Math.min(times * 50, 2000),
enableOfflineQueue: false
});
this.defaultTTL = 3600;
this.client.on('error', this.handleError);
}
async get(key, options = {}) {
try {
const cached = await this.client.get(key);
(cached) {
..(key);
.(cached);
}
..(key);
(options.) {
data = options.();
.(key, data, options.);
data;
}
;
} (error) {
.(error);
options. ? options.() : ;
}
}
() {
serialized = .(value);
(ttl) {
..(key, ttl, serialized);
} {
..(key, serialized);
}
(value.) {
( tag value.) {
..(, key);
}
}
}
() {
keys = ..();
(keys. > ) {
..(...keys);
..();
}
keys.;
}
() {
keys = ..(pattern);
(keys. > ) {
..(...keys);
}
keys.;
}
}
= () => {
(req, res, next) => {
(req. !== ) {
();
}
cacheKey = (req);
cached = cacheManager.(cacheKey);
(cached) {
res.(, );
res.(, cacheKey);
res.(cached);
}
originalSend = res.;
res. = () {
res. = originalSend;
(res. === ) {
cacheManager.(cacheKey, data, options.);
}
res.(, );
res.(, cacheKey);
res.(data);
};
();
};
};
app.(,
({ : }),
(req, res) => {
product = db.(req..);
res.(product);
}
);
Example 2: CDN Integration with Cache Purging
Scenario: Global content delivery with CloudFlare integration
Generated CDN Configuration:
class CDNManager {
constructor(config) {
this.zoneId = config.cloudflareZoneId;
this.apiToken = config.cloudflareApiToken;
this.baseUrl = 'https://api.cloudflare.com/client/v4';
}
setCacheHeaders(res, options = {}) {
const {
maxAge = 3600,
sMaxAge = 86400,
staleWhileRevalidate = 60,
staleIfError = 3600,
mustRevalidate = false,
public = true
} = options;
let cacheControl = public ? 'public' : 'private';
cacheControl += `, max-age=${maxAge}`;
cacheControl += `, s-maxage=${sMaxAge}`;
if (staleWhileRevalidate) {
cacheControl += `, stale-while-revalidate=${staleWhileRevalidate}`;
}
if (staleIfError) {
cacheControl += `, stale-if-error=${staleIfError}`;
}
if (mustRevalidate) {
cacheControl += ', must-revalidate';
}
res.set('Cache-Control', cacheControl);
res.(, options.?.() || );
res.(, );
}
() {
{ urls, tags, everything = } = options;
purgeBody = {};
(everything) {
purgeBody. = ;
} (tags) {
purgeBody. = tags;
} (urls) {
purgeBody. = urls;
}
response = (
,
{
: ,
: {
: ,
:
},
: .(purgeBody)
}
);
response.();
}
}
app.(, (req, res) => {
content = cms.(req..);
cdnManager.(res, {
: ,
: ,
: [, ]
});
res.(content);
});
app.(, (req, res) => {
content = cms.(req.., req.);
cdnManager.({
: []
});
cacheManager.();
res.({ : });
});
Example 3: Advanced Cache Warming and Preloading
Scenario: Critical data that must always be cached for performance
Generated Cache Warming Strategy:
class CacheWarmer {
constructor(cacheManager, dataSource) {
this.cache = cacheManager;
this.dataSource = dataSource;
this.warmingInterval = 5 * 60 * 1000;
}
async warmCache() {
console.log('Starting cache warming...');
const criticalData = [
{ key: 'homepage:featured', fetch: () => this.dataSource.getFeaturedProducts() },
{ key: 'categories:all', fetch: () => this.dataSource.getAllCategories() },
{ key: 'config:site', fetch: () => this.dataSource.getSiteConfig() }
];
const warmingPromises = criticalData.map(async ({ key, fetch }) => {
try {
const data = ();
..(key, data, );
{ key, : };
} (error) {
{ key, : , : error. };
}
});
results = .(warmingPromises);
.(, results);
results;
}
() {
.();
( {
.();
}, .);
}
}
Error Handling
Error: Redis Connection Failed
Symptoms: Cache operations timeout or fail
Cause: Redis server unavailable or misconfigured
Solution:
if (!redis.isReady()) {
console.warn('Cache unavailable, falling back to database');
return await database.query(sql);
}
Prevention: Implement circuit breaker pattern and health checks
Error: Cache Stampede
Symptoms: Multiple simultaneous cache misses cause database overload
Cause: Popular item expires, causing many requests to rebuild cache
Solution: Implement probabilistic early expiration or distributed locks
Error: Stale Data Served
Symptoms: Users see outdated information
Cause: Cache TTL too long or invalidation not triggered
Solution: Implement event-based invalidation and reduce TTL values
Configuration Options
Option: --ttl
- Purpose: Set default time-to-live for cache entries
- Values: Seconds (integer)
- Default: 3600 (1 hour)
- Example:
/cache --ttl 7200
Option: --strategy
- Purpose: Choose caching pattern
- Values:
cache-aside, write-through, write-behind
- Default:
cache-aside
- Example:
/cache --strategy write-through
Option: --cdn
- Purpose: Specify CDN provider
- Values:
cloudflare, fastly, cloudfront, akamai
- Default:
cloudflare
- Example:
/cache --cdn fastly
Best Practices
✅ DO:
- Use consistent cache key naming conventions
- Implement cache metrics and monitoring
- Set appropriate TTL values based on data volatility
- Use cache tags for grouped invalidation
- Implement graceful degradation on cache failure
❌ DON'T:
- Cache user-specific sensitive data without isolation
- Use overly long TTLs for frequently changing data
- Forget to handle cache failures gracefully
- Cache large objects that exceed memory limits
💡 TIPS:
- Add jitter to TTL values to prevent synchronized expiration
- Use cache warming for critical data paths
- Monitor cache hit ratios (aim for >80%)
- Implement separate caches for different data types
Related Commands
/api-rate-limiter - Implement rate limiting with Redis
/api-response-validator - Validate cached responses
/api-monitoring-dashboard - Monitor cache performance
/api-load-tester - Test cache effectiveness under load
Performance Considerations
- Cache hit ratio target: >80% for static content, >60% for dynamic
- Redis memory usage: ~1KB per cached object + overhead
- Network latency: <5ms for Redis, <50ms for CDN edge
- Typical improvements: 10x-100x response time reduction
Security Notes
⚠️ Security Considerations:
- Never cache authentication tokens or passwords
- Implement cache key signing to prevent injection
- Use separate cache instances for different security contexts
- Encrypt sensitive data before caching
- Implement proper access controls for cache management endpoints
Troubleshooting
Issue: Low cache hit ratio
Solution: Review cache key strategy and TTL values
Issue: Memory pressure on Redis
Solution: Implement LRU eviction policy and reduce object sizes
Issue: Cache invalidation not working
Solution: Verify tag associations and event triggers
Getting Help
Version History
- v2.0.0 - Complete rewrite with multi-level caching and CDN integration
- v1.0.0 - Initial Redis-only implementation
Last updated: 2025-10-11
Quality score: 9.5/10
Tested with: Redis 7.0, CloudFlare, Fastly, AWS CloudFront