Redis Caching Strategy
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Redis Caching Strategy in the Poixpixel Discord Bot project is designed to provide high-performance data retrieval and state management while ensuring system resilience. By utilizing Redis as a primary cache layer, the bot reduces the load on the PostgreSQL database for frequently accessed data and provides a fast storage medium for volatile game states, such as counting data.
The implementation follows a "graceful degradation" philosophy. If the Redis service becomes unavailable, the system is designed to continue functioning—either by falling back directly to the database or by disabling specific non-critical features. This ensures that the bot remains operational even during partial infrastructure failures.
Sources: src/db/redis.ts:50-70, CONTRIBUTING.md:435-438
Core Architecture and Connectivity
The caching layer is built on the ioredis library and managed through a centralized RedisManager. The system maintains an internal connection state (isRedisAvailable) and utilizes an exponential backoff strategy for reconnection attempts when the service is disrupted.
Connection Management Logic
The connection is initialized during the module's lifecycle. If the connection fails, the manager attempts to reconnect up to a maximum number of times defined in the configuration. If these attempts are exhausted, caching is disabled, and managers are notified via Discord.
This diagram illustrates the lifecycle of the Redis connection and its error-handling path.
Sources: src/db/redis.ts:20-25, src/db/redis.ts:65-95, src/db/redis.ts:135-155
Secure Connections
The bot supports TLS-encrypted connections to Redis. It attempts to load certificates from the ./certs/ directory (rootCA.pem, cache-key.pem, and cache-cert.pem). If certificate loading fails, it defaults to an insecure connection while logging a warning.
Sources: src/db/redis.ts:100-116
Data Operations and Utilities
The RedisManager provides a wrapper around standard Redis commands, automatically prefixing all keys with bot: to avoid collisions and checking connectivity before every operation.
Key Operations
| Function | Description | Return Type |
|---|---|---|
set(key, value, ttl) | Stores a string value with an optional expiration. | `Promise<'OK' |
setJson(key, value, ttl) | Serializes an object to JSON and stores it. | `Promise<'OK' |
get(key) | Retrieves a string value by key. | `Promise<string |
getJson(key) | Retrieves and parses a JSON string into an object. | `Promise<T |
incr(key) | Atomic increment of a numeric key. | `Promise<number |
del(key) | Removes a specific key from the cache. | `Promise<number |
flushRedisCache() | Flushes all keys with the bot: prefix (preserves counting data). | Promise<void> |
Sources: src/db/redis.ts:184-300
Cache-Aside Pattern
The database layer (db.ts) implements a withCache helper function. This function follows the cache-aside pattern: it first attempts to retrieve data from Redis; if not found (a "cache miss"), it fetches the data from the database using a provided function and then populates the cache for future requests.
This sequence diagram shows the data flow during a standard cached query operation.
Sources: src/db/db.ts:672-705
Feature-Specific Implementations
Counting System
The counting game uses Redis as its primary state store (key: bot:counting). This includes the current count, the ID of the last user to count, and mistake tracking. Because this data is volatile and updated frequently, Redis provides the necessary low-latency performance.
Sources: src/util/counting/countingManager.ts:25-45, src/util/counting/constants.ts:5
Maintenance and flushing
The backend-manager command allows administrators to manually flush the Redis cache. To prevent game disruption, the flushRedisCache function explicitly backs up the bot:counting data, performs a prefix-based scan and delete of other keys, and then restores the counting state.
Sources: src/db/redis.ts:316-390, src/commands/util/backend-manager.ts:184-210
Configuration
Redis settings are defined in the redis block of the configuration file.
| Option | Type | Default (Example) | Description |
|---|---|---|---|
redisConnectionString | String | REDIS_CONNECTION_STRING | The URI for the Redis instance (use rediss:// for TLS). |
retryAttempts | Number | 5 | Max attempts to reconnect before disabling caching. |
initialRetryDelay | Number | 500 | Starting delay (ms) for exponential backoff. |
Sources: config.example.json:44-52, src/util/configLoader.ts:30-45
Conclusion
The Redis Caching Strategy is a critical component for the bot's scalability and responsiveness. By providing a structured manager that handles connection resilience, TLS security, and a standardized cache-aside pattern, the system ensures that performance-intensive features like the counting game and frequent database lookups are handled efficiently while maintaining high availability.