Does Redis Work With Payload CMS?
Redis integrates seamlessly with Payload CMS as a caching layer, session store, and message broker for background jobs and webhooks.
Quick Facts
How Redis Works With Payload CMS
Payload CMS doesn't have built-in Redis support out of the box, but integrating Redis is straightforward since Payload runs on Node.js and uses Express. Developers typically use Redis for three primary purposes: caching database queries and API responses to reduce load, storing session data for authenticated users, and queuing background jobs via libraries like Bull or RabbitMQ. The integration pattern involves initializing a Redis client in your Payload config, then wrapping database queries or API endpoints with cache logic. For session management, middleware like `connect-redis` pairs perfectly with Payload's Express setup. Most developers add Redis during scaling, not initial setup, making it a natural evolution rather than a mandatory complexity. The combination gives you a production-grade CMS with high-performance caching without requiring a separate backend—everything stays in your Payload application.
Best Use Cases
Quick Setup
npm install redis ioredis payload expressimport { buildConfig } from 'payload/config';
import Redis from 'ioredis';
const redis = new Redis({
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379'),
retryStrategy: (times) => Math.min(times * 50, 2000),
});
export default buildConfig({
admin: { user: 'admin@payload.test' },
collections: [
{
slug: 'posts',
fields: [{ name: 'title', type: 'text', required: true }],
hooks: {
afterChange: [async ({ doc }) => {
await redis.del(`post:${doc.id}`);
}],
},
},
],
onInit: async (payload) => {
payload.redis = redis;
},
});
// Usage in endpoint or hook:
const cachedPost = await redis.get(`post:${id}`);
if (!cachedPost) {
const post = await payload.findByID({ collection: 'posts', id });
await redis.setex(`post:${id}`, 3600, JSON.stringify(post));
return post;
}
return JSON.parse(cachedPost);Known Issues & Gotchas
Cache invalidation complexity when Payload documents update—stale data served if not properly cleared
Fix: Use Payload's hooks (beforeChange, afterChange) to invalidate Redis keys when documents are modified. Implement a key naming convention like `doc:${collectionSlug}:${documentId}`
Redis connection failures cause cascading failures if not handled—missing fallback to direct database queries
Fix: Wrap Redis operations in try-catch blocks and fall back to database queries on connection failure. Use Redis client retry logic with exponential backoff
Memory exhaustion if TTLs aren't set on cached keys, causing Redis to consume all available RAM
Fix: Always set reasonable TTLs (e.g., 5-60 minutes) on cached keys. Monitor Redis memory usage with `redis-cli INFO memory`
Payload's local development doesn't require Redis, but production setup differs, creating environment inconsistencies
Fix: Run Redis in Docker locally via docker-compose for development to match production environment exactly
Alternatives
- •Memcached + Payload CMS: Simpler caching without message brokering; good for cache-only use cases
- •PostgreSQL with native caching + Payload CMS: Eliminates external dependency but requires tuning query cache
- •Vercel KV (managed Redis) + Payload CMS: Serverless Redis alternative if deploying on Vercel or Edge Runtime
Resources
Related Compatibility Guides
Explore more compatibility guides