Why you shouldn’t use Redis as a rate limiter: Part 1 of 2
A tour of the common Redis-based rate limiter implementations — and the correctness and performance traps each one hides.
We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Rate limiting and admission checks that help reduce overload and protect expensive work.
Set admission budgets for launch spikes and promos before excess work reaches your handlers.
Fewer moving parts to run and monitor. Spend less on Redis and ops.
Add via SDK. Keep your stack. Clear limits your customers understand.
UNDERSTAND OVERLOAD · KEEP USEFUL WORK MOVING
For developers, architects, and managers: 27 narrated lessons on why services overload and how to protect them. No cloud experience required. Start with one request, or jump to any lesson.
Four chapters, one learning path. Read or listen in any order. ~41 minutes total · Times shown at 1×.
Keep enough capacity to finish work and recover.
Contain one customer's excess without punishing everyone.
Reduce work entering a shared dependency when it slows.
Choose, combine, and test the right protections.
Read the explanation or use the course map above. Audio is optional.
Eligible minimum comparison
Only observations that still count enter the comparison.
Not the average or a percentile.
Illustrative measurements. Each example appears when the narration introduces it.
Read the numbered steps in order. The explanation below follows the narration.
Minimum means the fastest measurement that still counts.
The eligible recent minimum is a pressure signal with freshness and missing-data limits.
The eligible recent minimum is a pressure signal with freshness and missing-data limits.
Which latency number does the guard use? RateLimitly uses the minimum among recent eligible observations: the fastest measurement that still counts under the tracker's configured history rules. It is not an average or a percentile. Freshness means how recent an observation is.
Imagine the eligible measurements are eighty, ninety, and one hundred milliseconds. The minimum is eighty. Now imagine the eligible set contains six hundred, six hundred twenty, and seven hundred. Its minimum is six hundred. Even the fastest eligible operation is now slower than a five-hundred-millisecond threshold, so that guard refuses new work.
But if an old eighty-millisecond sample still counts, the minimum stays low. That old fast result can mask newer slow results until it stops being eligible. Sparse history means too few eligible observations. The current implementation treats insufficient history optimistically; a zero signal there is not proof of a healthy database.
Sharing reports improves what clients can observe together. Freshness, history settings, and independent resource bounds still matter. Do not interpret an old fast result or missing evidence as guaranteed spare capacity.
Eligibility determines which observations still count under the configured history rules. The minimum is the fastest of those—not an average, percentile, or exact queue length. Freshness describes how recent an observation is.
These three eligible measurements are 80, 90 and 100 ms. Find the smallest duration among the measurements that count under the configured history rules.
Of 80, 90 and 100 ms, the smallest duration is 80 ms. That is this eligible set’s minimum; it does not describe every request or prove spare database capacity.
Now the eligible set contains 600, 620 and 700 ms. This is a different example: the earlier 80-ms observation is not part of this set.
The minimum of 600, 620 and 700 ms is 600 ms. All eligible observations in this example are at least that slow.
The fastest eligible observation is 600 ms, above this guard’s illustrative 500-ms threshold. The comparison includes equality; the threshold is not a timer that cancels work.
Because 600 ms is at or above the positive 500-ms threshold, the guard refuses this new operation. Your application must obey the decision and skip the protected work.
If an old 80-ms observation still qualifies alongside newer 600, 620 and 700-ms observations, the minimum remains 80 ms. That can mask current pressure until the old observation stops being eligible.
This is a different limitation from an old fast observation: too few measurements qualify to satisfy the tracker’s required history. Missing evidence is not a measured fast response.
The current implementation treats insufficient history optimistically. Its zero signal in that case is not proof of a healthy database or measured spare capacity; independent resource bounds still matter.
Sharing real observations improves the common view. Freshness and history settings still determine the signal; keep independent resource bounds rather than treating old or missing evidence as guaranteed capacity.
Content revision: 07c7dd00db17
Download review copy (27 lessons)A zero signal came from insufficient history. Does zero prove the database is fast?
No. It represents optimistic handling of missing evidence, not a measured guarantee of health.
Keep tracker history settings consistent, supply actual observations, and test old fast samples, sparse history, and sudden slowdowns.
This is the eligible recent minimum, not an average, percentile, memory meter, or exact queue-depth measurement.
Start here. No earlier lesson is required.
100 arrivals/s − 80 completions/s = 20 extra unfinished requests/s.
The tracker observes; the guard decides; your application enforces the decision.
A lingering fast sample can delay refusal; optimistic sparse history can reopen admission. Bound resources independently and test the full feedback delay.
Original explanation inspired by Fred Hébert and operational references; no endorsement implied.
AI-generated narration: ElevenLabs Eleven v3, Daniel stock voice. Audio streams only when you start listening.
A tour of the common Redis-based rate limiter implementations — and the correctness and performance traps each one hides.
The myth of infinite serverless scale — why adding machines doesn’t fix overload, and what to do instead.