Performance and Limits: Redis Ops, Memory, and When to Scale
This page explains what each request costs in Redis operations, how much memory each algorithm uses, and when to scale Redis or the application.
What a single request does
Every request hits the filter, resolves configuration, and executes a Lua script in Redis. The Lua script is the primary cost. Here are the Redis operations per algorithm:
| Algorithm | Redis ops per request | Notes |
|---|---|---|
| Token Bucket | 3 | HMGET, HMSET, PEXPIRE |
| Leaky Bucket | 3 | HMGET, HMSET, PEXPIRE |
| Fixed Counter | 3 | INCR, EXPIRE, TTL |
| Sliding Window Log | 4 | ZREMRANGEBYSCORE, ZADD, ZCARD, EXPIRE |
All operations run inside a single Lua script, so they are atomic and executed on the Redis server. The cost scales with key cardinality and with the number of entries in the Sliding Window sorted set.
Redis memory footprint per algorithm
These are approximate figures per IP + endpoint. Your numbers will vary based on Redis version and data structure overhead, but the order of magnitude is stable.
| Algorithm | Approx state per IP + endpoint | Key driver |
|---|---|---|
| Token Bucket | ~150 bytes | Two hash fields |
| Leaky Bucket | ~150 bytes | Two hash fields |
| Fixed Counter | ~50 bytes | Single string counter |
| Sliding Window Log | ~50 bytes per request in window | One zset entry per request |
Example: Sliding Window at 100 requests per minute keeps roughly 100 entries in the sorted set, which is about 5 KB per IP + endpoint. At 10,000 IPs, that is roughly 50 MB. If your limits allow thousands of requests per minute, the memory cost rises quickly.
What latency to expect
In a typical deployment where Redis is on the same network, algorithm execution is the dominant portion of the request cost. A cached configuration lookup is microseconds; a MongoDB lookup on first-seen IPs can add 5-15ms.
Typical end-to-end ranges from the design measurements:
- Cached config: 2-5ms
- MongoDB miss: 8-20ms
- Redis unavailable: 30-100ms (timeout)
If you see higher numbers, check Redis network latency first. Redis round-trip time dominates total request latency.
When to scale
Scale when you observe one of these signals:
- Redis CPU is consistently high during peak hours.
- Redis memory grows faster than expected due to high cardinality keys or Sliding Window usage.
- 95th percentile request latency rises during traffic spikes.
- You are adding more app instances but throughput is not increasing.
The service shares Redis state across all app instances. That makes the app horizontally scalable, but it shifts the bottleneck to Redis. If you scale app instances beyond 3-4, you typically see diminishing returns unless Redis is scaled as well.
Practical tuning steps
- Choose algorithms with memory in mind. Sliding Window is the most accurate but the most expensive.
- Keep TTLs realistic. Long TTLs plus high cardinality keys are a common cause of Redis memory growth.
- Increase Redis connection pool size if you see request queueing on the client.
- Move Redis closer to the app if network latency is the main contributor.
- Use Redis replication or cluster when read/write throughput exceeds a single node.
What to verify
Track rate_limiter_requests_total and rate_limiter_decision_time_seconds in Prometheus, and monitor Redis CPU and memory. The most reliable early warning is rising decision time coupled with increasing Redis memory usage.