Redis acts as the hot-path lookup cache inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/backtest-kit/backtest-monorepo-parallel/llms.txt
Use this file to discover all available pages before exploring further.
backtest-monorepo-parallel, sitting in front of MongoDB on every findByContext call. Before any query reaches Mongo, BaseMap issues a Redis GET on localhost — a single round-trip that typically resolves in under a millisecond. This O(1) read characteristic is a primary reason the parallel runner sustains ~103 events/second and ~6,300× aggregate real-time replay speed across nine symbols in a single Node process.
Docker Setup
Start Redis with a single command:docker/redis/docker-compose.yaml
Connection Configuration
Redis connection parameters are read from environment variables, with sensible defaults for local development. They are resolved inpackages/core/src/config/params.ts:
packages/core/src/config/params.ts
| Variable | Default | Purpose |
|---|---|---|
CC_REDIS_HOST | 127.0.0.1 | Hostname or IP address of the Redis server |
CC_REDIS_PORT | 6379 | TCP port Redis listens on |
CC_REDIS_USER | default | ACL username (Redis 6+ ACL; default uses the legacy password mode) |
CC_REDIS_PASSWORD | mysecurepassword | ACL password matching --requirepass in the Compose file |
How BaseMap Uses Redis
BaseMap is a factory class (using di-factory) that wraps an ioredis client obtained from getRedis() and implements a namespaced, TTL-aware key/value store. Every cache-line operation maps to a single Redis command.
Key Namespacing
Every key stored by aBaseMap instance is prefixed with the instance’s connectionKey:
packages/core/src/lib/common/BaseMap.ts
BaseMap instances with different connectionKey values never collide, even when they store entries under the same logical key. All scan patterns are scoped to ${connectionKey}:*.
Write with Optional TTL
packages/core/src/lib/common/BaseMap.ts
ttlExpireSeconds is a positive integer, EXPIRE is called immediately after SET, making the entry evict itself automatically. When ttlExpireSeconds is -1, the EXPIRE call is skipped entirely and the entry persists until explicitly deleted.
The default TTL is 5 * 60 seconds (5 minutes):
packages/core/src/lib/common/BaseMap.ts
Read
packages/core/src/lib/common/BaseMap.ts
get resolves with null on a cache miss, allowing the caller to fall back to MongoDB. No JSON parsing occurs on the critical path — values are stored and returned as raw strings.
SCAN-Based Iteration
All bulk operations (clear, toArray, iterate, keys, values, size) use Redis SCAN with a batch size of 100 to avoid blocking the server:
packages/core/src/lib/common/BaseMap.ts
SCAN is non-blocking and cursor-based, so it does not hold a server-side lock across batches. The loop terminates when Redis returns cursor "0" (or 0), indicating the full keyspace has been traversed.
BaseMap API Reference
set(key, value)
set(key, value)
Stores
value under connectionKey:key. Calls EXPIRE with ttlExpireSeconds unless TTL is -1.get(key)
get(key)
Returns the stored value as a string, or
null on a miss. Accepts null as input and returns null immediately (no Redis round-trip).has(key)
has(key)
Returns
true if EXISTS returns 1 for the namespaced key.delete(key)
delete(key)
Issues
DEL for the namespaced key. A null key is a no-op.clear()
clear()
SCAN-iterates all keys matching
connectionKey:* in batches of 100, deleting each batch atomically with DEL.toArray()
toArray()
SCAN-iterates all matching keys and bulk-fetches their values with
MGET, returning [key, value] pairs with the connectionKey: prefix stripped from each key.iterate() / keys() / values()
iterate() / keys() / values()
Async generator variants of
toArray() for streaming consumption without materialising the full result set.size()
size()
SCAN-counts all matching keys and returns the total. Does not fetch values.
Adding a New Redis-Cached Lookup
To add a new Redis-backed cache, extendBaseMap with your chosen connectionKey and TTL strategy:
BaseMap operations are available immediately. No additional Redis configuration is required — the client is shared through the getRedis() singleton from @backtest-kit/mongo.