Skip to content

Overhauling caching feature #8457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

nhtruong
Copy link
Contributor

@nhtruong nhtruong commented Jul 14, 2025

LibreChat employes 2 different Redis client libraries (built-in node.js client via Keyv, and ioredis) and 3 different Redis wrappers (@keyv/redis, rate-limit-redis, and connect-redis). It supports various Redis features like prefix, namespace, ttl, tls, cluster and so on but these features are not consistently applied to said redis libraries. Calls to instantiate redis cache stores are also also not centralized, leading to caching logic bleeding into other sections of the app.

This PR is an attempt to overhaul caching for LibreChat (esp Redis) for better maintainability, while fixing several features regarding Redis:

Configuration Management

  • New centralized config: api/cache/cacheConfig.js is a one-stop-shop that reads and parses ENV vars used for caching.
  • Dynamic key prefixing: Support for REDIS_KEY_PREFIX_VAR to use environment variables (e.g., deployment IDs) as Redis key prefixes
  • Enhanced .env.example: Comprehensive Redis configuration examples including cluster, TLS, and authentication options

Architecture Improvements

  • Simplified client management: api/cache/redisClients.js replaces complex client creation logic in the old ioredisClient.js and keyvRedis.js (notably using URL package to handle the complex parsing of the old mapURI function)
  • Cache factory pattern: api/cache/cacheFactory.js provides unified cache creation methods (redisCache, sessionCache, violationCache, limiterCache)
  • Caching creation logic has been DRY'ed and moved out of middleware/limiters
  • All keys for getLogStores are now properly mapped to an enum value.

Fixes for features that didn't work or weren't implemented consistently

  • Global prefix and namespace for Redis keys.
  • Connecting to a redis cluster.
  • Setting max listeners
  • Certificate Authority for TLS
  • Keeping the connection alive

I also added complete Redis cluster setup scripts and configurations in redis-config/ to help with local testing of the above features. Check is redis-config/README.md file for more details.

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Testing

Please describe your test process and include instructions so that we can reproduce your test. If there are any important variables for your testing configuration, list them here.

Test Configuration:

Checklist

Please delete any irrelevant options.

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • I have made pertinent documentation changes
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

@nhtruong nhtruong marked this pull request as ready for review July 14, 2025 19:22
- Refactored caching logic.
- Fixed redis prefix, namespace, tls, ttl, and cluster.
- Added REDIS_KEY_PREFIX_VAR
[CacheKeys.ENCODED_DOMAINS]: new Keyv({ store: keyvMongo, namespace: CacheKeys.ENCODED_DOMAINS }),
[CacheKeys.ABORT_KEYS]: redisCache(CacheKeys.ABORT_KEYS, Time.TEN_MINUTES),
[CacheKeys.TOKEN_CONFIG]: redisCache(CacheKeys.TOKEN_CONFIG, Time.THIRTY_MINUTES),
[CacheKeys.GEN_TITLE]: redisCache(CacheKeys.GEN_TITLE, Time.TWO_MINUTES),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we call it redisCache here but does it mean it's in-memory if Redis is not activated?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good question, thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching that. I've renamed it to standardCache and also added function comments for cache factories to explain their types and use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants