Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

LuaintermediatebackendAI generated

Redis Lua Scripting for Atomic Rate Limiter

Build a rate limiter (the component that stops a client from making, say, more than 100 requests per minute) as a Lua script that runs inside Redis. Because Redis runs a script from start to finish without anything else happening in between, checking the count and recording the new request happen as one atomic step, so even hundreds of servers checking at the same moment can never let a client go over the limit. You'll implement a sliding window, wrap it in a small Lua client library using redis-lua, and prove it's correct under heavy concurrency. You'll learn Redis data structures (sorted sets), Lua scripting with EVAL and EVALSHA, why atomicity matters in distributed systems, and how to test and measure concurrent code.

Estimate
~10h
Steps
6
Completed by
0
Proposed by
codeseed.app

Redis · redis-lua

Project roadmap

  1. 01

    Design the algorithm

    ~1.5h

    Write DESIGN.md comparing a fixed window, a sliding window log and a token bucket, and choose the sliding window log: each client has a sorted set whose members are request ids and whose scores are timestamps in milliseconds. Describe the key naming (ratelimit:{client}), what the script receives (the key, the limit, the window size, the current time and a unique request id) and returns (allowed, remaining and retry after). Done when: DESIGN.md explains the choice and the data layout.

  2. 02

    Write the Lua script

    ~2h

    Write ratelimit.lua for Redis: remove entries older than the window with ZREMRANGEBYSCORE, count the rest with ZCARD, and if under the limit, add the request with ZADD, otherwise compute when the oldest entry expires. Set the key's expiry to the window size so idle clients disappear. Read inputs only from KEYS and ARGV. Test it by hand with redis-cli --eval. Done when: calling the script repeatedly allows exactly the limit, then refuses.

  3. 03

    Build the client library

    ~1.5h

    Write a Lua module using redis-lua that loads the script once with SCRIPT LOAD, calls it with EVALSHA, and reloads it automatically when Redis answers NOSCRIPT (for example after a restart). Expose a function check(client_id) returning allowed, remaining and retry_after. Decide what happens when Redis is unreachable (allow or deny) and make it a setting. Done when: the library works, and still works after SCRIPT FLUSH.

  4. 04

    Prove it under concurrency

    ~2h

    Write a test that starts many processes (for example 20 Lua processes, or a small Go or Python program) all calling the limiter for the same client at the same moment, with a limit of 100 per window. Count the allowed requests across all processes. Then do the same with a naive version (GET, then INCR in separate commands) to show it can go over the limit. Done when: the script never allows more than 100, and the naive version is shown to fail.

  5. 05

    Measure performance

    ~1.5h

    Measure calls per second and latency with many clients using redis-benchmark or your own load script, on your own machine. Compare memory use per client at different limits (a sorted set stores every request in the window), and document when a token bucket would be a better choice. Done when: README.md shows the throughput, latency and memory numbers.

  6. 06

    Test edge cases

    ~1.5h

    Write tests with busted against a real local Redis: the window sliding correctly over time, requests exactly at the window edge, different clients not affecting each other, keys expiring when idle, and the retry_after value. Done when: busted passes.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~10h · 6 steps

Tech stack

Redisredis-lua