Redis Cache Architecture#
Overview#
RAGFlow uses Redis (via the Valkey client) as a shared cache for three categories of expensive operations: LLM completions, embedding vectors, and TTS audio. The singleton RedisDB class in rag/utils/redis_conn.py wraps a valkey.StrictRedis connection and exposes get, set, mget, and set_obj primitives used by all cache layers. A module-level REDIS_CONN singleton is imported by all callers .
Redis also serves task queuing (Streams API) and distributed locking, but those are separate concerns from caching.
Cache Layers#
1. LLM Completion Cache#
Location: rag/graphrag/utils.py — get_llm_cache / set_llm_cache
- Key: xxHash64 of
llm_name + prompt_text + chat_history + gen_config - TTL: 24 hours
- Value: Raw UTF-8 encoded completion string
- Used by: GraphRAG entity/relation extraction, keyword extraction, and other LLM-driven pipeline steps
The key covers all four dimensions that affect the output, so changing any generation parameter (temperature, model, history) produces a distinct cache key and cache miss.
2. Embedding Cache#
Location: rag/graphrag/utils.py — get_embed_cache / set_embed_cache
- Key: xxHash64 of
llm_name + input_text(model name and text hashed sequentially) - TTL: 24 hours
- Value: JSON-serialized list (numpy arrays are converted via
.tolist()before storage) - Used by: GraphRAG node/edge embedding during
set_graphandgraph_node_to_chunk/graph_edge_to_chunk
A batch helper _batch_embed_cache_misses issues a single MGET call to check many keys at once, avoiding per-item round-trips when pre-warming embeddings for large knowledge graphs .
3. TTS Audio Cache#
Location: rag/utils/tts_cache.py — synthesize_with_cache
- Key:
tts:cache:<model_id>:<sha256(text)>— uses SHA-256 (not xxHash64) for the text digest, prefixed withtts:cache:and the model's ID - TTL: 7 days by default; overridable via
RAGFLOW_TTS_CACHE_TTL_SECONDSenv var ; set to0to disable caching - Value: Hex-encoded binary audio blob (
binascii.hexlify) - Used by: Any code path that calls TTS synthesis; the function wraps the model call transparently
The TTS cache uses a structured key prefix (tts:cache:) unlike the bare-hash keys used for LLM and embedding caches, making TTS entries easily identifiable in Redis.
4. Tag Cache (Minor)#
Location: rag/graphrag/utils.py — get_tags_from_cache / set_tags_to_cache
- Key: xxHash64 of
kb_ids - TTL: 600 seconds (10 minutes) — much shorter due to higher mutation frequency
- Value: JSON-serialized tag data
Key Design Summary#
| Cache | Hash | Key Inputs | TTL | Value Format |
|---|---|---|---|---|
| LLM completions | xxHash64 | model + text + history + genconf | 24h | UTF-8 string |
| Embeddings | xxHash64 | model + text | 24h | JSON float list |
| TTS audio | SHA-256 | tts:cache:<model_id>:<sha256(text)> | 7d (configurable) | Hex string |
| Tags | xxHash64 | kb_ids | 10min | JSON |
Infrastructure#
Client: RAGFlow uses the valkey Python package as a drop-in Redis client . Connection config is read from settings.decrypt_database_config(name="redis") or a fallback get_base_config call .
Default DB: DB index 1 .
Singleton pattern: RedisDB is decorated with @singleton , ensuring one connection pool per process. All reconnection on exception is handled internally .
Lua scripts: Two Lua scripts are registered at startup — lua_delete_if_equal (atomic compare-and-delete, used by RedisDistributedLock) and lua_token_bucket (rate limiting) .
Key Source Files#
| File | Purpose |
|---|---|
rag/utils/redis_conn.py | RedisDB singleton, all primitive ops, distributed lock, stream queuing |
rag/graphrag/utils.py | LLM cache, embedding cache, tag cache, batch MGET helper |
rag/utils/tts_cache.py | TTS audio cache with SHA-256 keying and configurable TTL |