Skip to content

Cache design

How OpenQuok uses Redis and Postgres — source of truth, cache strategy, and connection limits.

3 min read

Connect your agent today

Draft from chat, review in your calendar, and publish only what you approve.

Start for $0

Overview

OpenQuok stores product data in Supabase (Postgres). Redis is a shared helper for cache, OAuth state, and job queues. Redis is not the source of truth for posts, users, or billing.

Configure Redis connection variables on Redis cache. Use Redis & queues for BullMQ keys and redis-cli checks.

Source of truth

DataSource of truth
Posts, schedules, integrations, users, orgs, billingPostgres
API read cache (profiles, RBAC, calendar lists, blog, listings)Postgres (copy in Redis)
OAuth PKCE stateRedis (short TTL; not a DB copy)
BullMQ jobs and Flowcraft run stateRedis (pipeline only; schedule rows stay in Postgres)

Write scheduled posts to Postgres before you enqueue a worker job. If Redis loses a job, reconciliation can rescan Postgres. Do not treat the queue as the schedule record.

Three Redis roles

One Redis host can serve all roles. The API and workers use two clients:

RoleClientKey examples
Application cacheredis package (RedisCacheProvider)REDIS_PREFIX (default app:cache:)
Queues and workflowioredis / BullMQbull:<queue>:*, workflow:state
OAuth connectSame cache clientlogin:, organization:, … under the cache prefix

Optional REDIS_BULLMQ_DB puts queue keys on a separate logical DB. Cache keys use REDIS_DB.

Cache strategy

Reads — read-aside. Services call getOrSet: read Redis; on miss, load Postgres, then set Redis with TTL. Code: backend/connections/cache/CacheService.ts.

Writes — write-around. Mutations write Postgres first. Then CacheInvalidationService deletes keys or patterns (for example calendar list caches after a post change). OpenQuok does not write-through every read cache on each DB update.

TTL — backstop. Default CACHE_DEFAULT_TTL is 900 seconds. OAuth state TTL is 3600 seconds. Stale data can exist until invalidation or TTL expiry.

Production must use CACHE_PROVIDER=redis (or Redis env with auto-force in production) so OAuth state works across Vercel instances.

Connection limits

Managed Redis plans cap concurrent connections (for example 256 on Redis Cloud Essentials 250 MB).

ComponentTypical connections
Each warm Vercel API instance1 cache client + short-lived queue clients on enqueue
Each Railway worker1–2 persistent ioredis clients (BullMQ) + optional cache client
Health probesCan open extra clients if each probe creates a new connection

Traffic spikes can raise connection count fast. Redis does not remove idle clients for you. Stale TCP sessions can stay until the client disconnects or you run CLIENT KILL.

Check connections

redis-cli -u 'redis://default:PASSWORD@HOST:PORT' --tls INFO clients | grep connected_clients
redis-cli -u 'redis://...' --tls CLIENT LIST

Kill only clients with idle over one day and no recent bzpopmin / setex activity. Do not kill live worker or API rows.

Search documentation
Find a docs page
Discord Support