Rate Limiting Overview: Concepts, Architectures, Algorithms, and Redis + Lua Token‑Bucket Implementation
This article explains what rate limiting is, why it is needed, the typical actions triggered by limiting, compares single‑node and distributed architectures, reviews four common limiting algorithms, and provides a detailed Redis‑Lua token‑bucket implementation with full source code.
Rate limiting controls the number of requests reaching a system to ensure stability, protect resources, and enforce usage policies. It is essential when facing traffic spikes, malicious attacks, or usage‑based billing.
Why rate limiting – Uncontrolled request bursts can exhaust CPU, memory, and cause timeouts or crashes; limiting also enables charging per request.
Limiting actions include rejecting excess requests, service degradation, privileged request handling, delayed processing via queues, and auto‑scaling.
Architectures
In a single‑node deployment, limiting is applied locally to protect the node and its downstream services. In a clustered environment, per‑node limiting can lead to uneven request handling, so a distributed approach using shared middleware (e.g., Redis) is preferred to enforce a global limit.
Limiting algorithms
1. Fixed window counter – Simple to implement but can allow up to twice the limit within a sliding second.
2. Sliding window counter – Tracks request timestamps to provide more accurate limits at the cost of higher memory usage.
3. Leaky bucket – Models requests as water droplets flowing out at a constant rate, smoothing traffic but delaying burst handling.
4. Token bucket – Generates tokens at a steady rate, allowing bursts while maintaining an overall rate; widely used in industry.
Token‑bucket implementation with Redis + Lua
Redis hashes store limiter state (last_time, curr_permits, bucket_cap, period, rate). The Lua script atomically updates tokens based on elapsed time, checks availability, and returns 1 for success, 0 for limit exceeded, or -1 for missing configuration.
local key = KEYS[1] -- 要进行限流的Key,可以是 uri
local consume_permits = tonumber(ARGV[1]) -- 请求消耗的令牌数,每个请求消耗一个
local curr_time = tonumber(ARGV[2]) -- 当前时间
local limiter_info = redis.pcall("HMGET", key, "last_time", "curr_permits", "bucket_cap", "rate", "period")
if not limiter_info[3] then
return -1
end
local last_time = tonumber(limiter_info[1]) or 0
local curr_permits = tonumber(limiter_info[2]) or 0
local bucket_cap = tonumber(limiter_info[3]) or 0
local rate = tonumber(limiter_info[4]) or 0
local period = tonumber(limiter_info[5]) or 0
local total_permits = bucket_cap
local is_update_time = true
if last_time > 0 then
local new_permits = math.floor((curr_time-last_time)/1000 * rate)
if new_permits <= 0 then
new_permits = 0
is_update_time = false
end
total_permits = new_permits + curr_permits
if total_permits > bucket_cap then
total_permits = bucket_cap
end
else
last_time = curr_time + period * 1000
end
local res = 1
if total_permits >= consume_permits then
total_permits = total_permits - consume_permits
else
res = 0
end
if is_update_time then
redis.pcall("HMSET", key, "curr_permits", total_permits, "last_time", curr_time)
else
redis.pcall("HSET", key, "curr_permits", total_permits)
end
return resTo use the script, first load it with SCRIPT LOAD to obtain its SHA1, then invoke EVALSHA for each request, passing the request URI as the key and the current timestamp. The return value determines whether the request passes, is limited, or lacks configuration.
Summary – Fixed window is simple but inaccurate; sliding window improves accuracy at memory cost; leaky bucket smooths traffic but cannot handle bursts; token bucket combines the advantages of the others and is the most widely adopted solution, especially when implemented with Redis and Lua.
References
https://www.nginx.com/blog/rate-limiting-nginx/
https://www.infoq.cn/article/qg2tx8fyw5vt-f3hh673
https://segmentfault.com/a/1190000019676878
https://en.wikipedia.org/wiki/Token_bucket
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
