Storage Backends
Table of Contents
- Memory Store
- Redis Store
- CacheHubStore Atomic Backend
- Custom Stores
- Performance and Memory
- Selection Decision Tree
- Recommended Configurations
- Lifecycle and Ownership
- Related Documents
Memory Store
MemoryStore is the default backend. It stores counters in the current Node.js process.
Advantages
- No external service required.
- Very low latency because all operations stay in process.
- Good for local development, tests, command-line tools, single-instance services, and low-complexity deployments.
Limitations
- Counters are not shared across processes.
- Restarting the process clears all counters.
- Horizontal scaling requires a shared backend such as Redis.
When to Use Memory
Use MemoryStore when one process owns the full key space, or when strict distributed consistency is not required.
Redis Store
Use RedisStore when multiple application instances must share counters.
Option 1: Connection String
This form creates a Redis client owned by the limiter. Call await limiter.close() when the process shuts down.
Option 2: ioredis Client
External clients are caller-owned by default. Set ownsClient: true if RedisStore.close() or RateLimiter.close() should close the client.
Option 3: Redis Cluster
Use cluster when the key space or Redis throughput requires horizontal Redis scaling. Watch for hot keys and slot distribution.
Option 4: Redis Sentinel
Use Sentinel when you need Redis failover while keeping a single logical primary.
CacheHubStore Atomic Backend
CacheHubStore uses cache-hub@2.2.4 atomic state primitives. It keeps flex-rate-limit as the algorithm and middleware layer while delegating high-concurrency state updates to cache-hub.
Characteristics
- Supports fixed-window, sliding-window, token-bucket, and leaky-bucket state through cache-hub primitives.
- The Redis path uses cache-hub Lua-backed atomic operations.
- The no-client memory path can be useful in tests and short-lived local scenarios.
- In-memory cache-hub state prunes expired fixed-window, sliding-window, token-bucket, and leaky-bucket entries automatically.
await limiter.close()closes owned cleanup timers or cache resources.
Rollback Integration
CacheHubStore supports rollback data for middleware features such as skipFailedRequests and skipSuccessfulRequests.
Custom Stores
Implement the Store contract when you need a project-specific backend.
For algorithm-specific optimization, a custom store can also implement checkSlidingWindow, checkTokenBucket, checkLeakyBucket, and rollback methods.
Performance and Memory
These are guidance points, not universal QPS guarantees. Actual throughput depends on Node.js version, CPU, network latency, Redis deployment, algorithm, key distribution, and application work.
Approximate Memory Considerations
- Memory: state lives in the Node.js process and scales with key count and algorithm state.
- Redis: application memory is small, while serialized state is held in Redis.
- Sliding window stores more per-key data than fixed-window.
- Token bucket and leaky bucket usually keep compact per-key state.
Performance Notes
- Memory is typically the fastest single-process path.
- Redis is affected by network round trips, pipelining/Lua strategy, and Redis CPU.
- Redis Cluster is affected by slot routing and hot keys.
- CacheHubStore is most useful when Redis atomic update behavior matters.
See Benchmark and Performance for current reproducible benchmark commands.