@meui-creative/payload-redis-cache
v0.1.1
Published
Redis caching plugin for Payload CMS with automatic invalidation
Downloads
6
Maintainers
Readme
Payload Redis Cache Plugin
A high-performance Redis-based caching plugin for Payload CMS with automatic cache invalidation and flexible configuration.
Features
- 🚀 Redis Caching: Fast in-memory caching for Local API operations
- 🔄 Auto Invalidation: Automatic cache invalidation on document changes/deletes
- ⚙️ Flexible Configuration: Per-collection/global cache strategies
- 🏷️ Tag-based Invalidation: Intelligent cache invalidation using tags
- 📊 Cache Statistics: Built-in cache statistics and monitoring
- 🔧 Manual Cache Management: Utilities for programmatic cache control
- 🛡️ Error Resilient: Graceful fallback when Redis is unavailable
Requirements
- Payload CMS: ^3.37.0
- Redis: 5.0+ (local or cloud instance)
- Node.js: ^18.20.2 || >=20.9.0
Installation
npm install @meui-creative/payload-redis-cache redis
# or
yarn add @meui-creative/payload-redis-cache redis
# or
pnpm add @meui-creative/payload-redis-cache redisQuick Start
1. Configure the Plugin
// payload.config.ts
import { payloadRedisCache } from '@meui-creative/payload-redis-cache'
export default buildConfig({
// ... your config
plugins: [
payloadRedisCache({
redis: {
url: 'redis://localhost:6379'
},
collections: {
posts: true,
products: {
ttl: 1800, // 30 minutes
operations: ['find', 'findByID']
}
},
globals: {
settings: true
}
})
]
})2. Use Cached Operations
import { cachedFind, cachedFindByID } from '@meui-creative/payload-redis-cache'
// In your application code
const posts = await cachedFind(payload, {
collection: 'posts',
where: { status: { equals: 'published' } }
})
const post = await cachedFindByID(payload, {
collection: 'posts',
id: 'post-id'
})Configuration
Plugin Options
interface PayloadRedisCacheConfig {
redis: {
url: string // Redis connection URL
options?: RedisClientOptions // Additional Redis options
}
cache?: {
defaultTTL?: number // Default TTL in seconds (default: 3600)
keyPrefix?: string // Cache key prefix (default: 'payload:')
debug?: boolean // Enable debug logging (default: false)
}
collections?: {
[slug]: boolean | CacheStrategy
}
globals?: {
[slug]: boolean | CacheStrategy
}
invalidation?: {
autoInvalidate?: boolean // Auto-invalidate on changes (default: true)
patterns?: InvalidationPattern[]
}
disabled?: boolean // Disable plugin completely
}Cache Strategy Options
interface CacheStrategy {
ttl?: number // TTL in seconds
enabled?: boolean // Enable/disable caching
operations?: CacheOperation[] // Operations to cache
tags?: string[] // Custom cache tags
}
type CacheOperation = 'find' | 'findByID' | 'count' | 'findGlobal'Configuration Examples
Basic Configuration
payloadRedisCache({
redis: { url: 'redis://localhost:6379' },
collections: {
posts: true, // Use defaults
products: true,
users: false // Don't cache users
}
})Advanced Configuration
payloadRedisCache({
redis: {
url: process.env.REDIS_URL,
options: {
password: process.env.REDIS_PASSWORD,
db: 1
}
},
cache: {
defaultTTL: 3600,
keyPrefix: 'myapp:',
debug: process.env.NODE_ENV === 'development'
},
collections: {
posts: {
ttl: 1800, // 30 minutes
operations: ['find', 'findByID'], // Only cache these operations
tags: ['content'] // Custom tags
},
products: {
ttl: 7200, // 2 hours
operations: ['find', 'findByID', 'count']
}
},
globals: {
settings: { ttl: 86400 } // 24 hours
}
})Usage Examples
Cached Operations
import {
cachedFind,
cachedFindByID,
cachedCount,
cachedFindGlobal
} from '@meui-creative/payload-redis-cache'
// Cached collection operations
const posts = await cachedFind(payload, {
collection: 'posts',
where: { status: { equals: 'published' } },
limit: 10,
sort: '-createdAt'
})
const post = await cachedFindByID(payload, {
collection: 'posts',
id: 'post-id',
depth: 2
})
const count = await cachedCount(payload, {
collection: 'posts',
where: { status: { equals: 'published' } }
})
// Cached global operations
const settings = await cachedFindGlobal(payload, {
slug: 'settings',
depth: 1
})Manual Cache Management
import {
invalidateCollection,
invalidateGlobal,
clearAllCache,
getCacheStats
} from '@meui-creative/payload-redis-cache'
// Invalidate specific collection
await invalidateCollection(payload, 'posts')
await invalidateCollection(payload, 'posts', 'specific-id')
// Invalidate global
await invalidateGlobal(payload, 'settings')
// Clear all cache
await clearAllCache(payload)
// Get cache statistics
const stats = await getCacheStats(payload)
console.log(`Cache keys: ${stats.keys}, Memory: ${stats.memory}`)Custom Cache Operations
import { setCacheData, getCacheData } from '@meui-creative/payload-redis-cache'
// Set custom cache data
await setCacheData(payload, 'custom:key', { data: 'value' }, 3600, ['custom'])
// Get custom cache data
const data = await getCacheData(payload, 'custom:key')How It Works
Automatic Cache Invalidation
The plugin hooks into Payload's afterChange and afterDelete hooks to automatically invalidate related cache entries when documents are modified or deleted.
Cache Keys
Cache keys are generated based on:
- Collection/Global slug
- Operation type (find, findByID, etc.)
- Operation parameters (where clauses, depth, locale, etc.)
- Document ID (for findByID operations)
Example cache keys:
payload:collection:posts:find:eyJ3aGVyZSI6eyJzdGF0dXMiOnsiZXF1YWxzIjoicHVibGlzaGVkIn19fQ==
payload:collection:posts:findByID:post-123
payload:global:settings:findGlobalCache Tags
Cache entries are tagged for efficient invalidation:
collection:posts- All posts collection entriescollection:posts:123- Specific post with ID 123global:settings- Settings global entries
Performance Considerations
Redis Connection
- Uses a single Redis connection per Payload instance
- Automatic reconnection on connection loss
- Connection pooling handled by Redis client
Cache Size Management
- TTL-based expiration prevents unlimited growth
- Manual cache clearing utilities available
- Monitor cache size using
getCacheStats()
Error Handling
- Graceful fallback to regular Payload operations if Redis unavailable
- Errors logged but don't break application functionality
- Cache operations are non-blocking
Environment Variables
# Redis connection
REDIS_URL=redis://localhost:6379
# Redis with authentication
REDIS_URL=redis://username:password@localhost:6379
# Redis Cloud
REDIS_URL=redis://your-redis-cloud-endpoint:6379Troubleshooting
Common Issues
Redis connection failed
- Ensure Redis is running and accessible
- Check REDIS_URL environment variable
- Verify network connectivity and firewall settings
Cache not working
- Check plugin configuration
- Verify collections/globals are enabled for caching
- Enable debug logging to see cache operations
Memory usage high
- Reduce TTL values
- Implement cache size limits in Redis configuration
- Use
clearAllCache()periodically
Debug Mode
Enable debug logging to monitor cache operations:
payloadRedisCache({
cache: { debug: true },
// ... other config
})This will log:
- Cache hits and misses
- Cache setting operations
- Cache invalidation operations
- Error messages
License
MIT License - see LICENSE file for details.
Made with ❤️ by MEUI Creative
