Nice walkthrough. Two things worth adding for anyone taking this to production. Fixed-window counters have a boundary stampede problem: a burst at the end of one window plus a burst at the start of the next can double the intended rate. Sliding-window log or token bucket fixes it. The in-memory approach breaks the moment you run more than one replica, each instance gets its own budget. The standard production answer is a Redis-backed token bucket (a small Lua script keeps the check-and-decrement atomic). Happy to sketch it if useful.
Thank you for pointing these out! I'm still learning about rate limiting, so this was mainly an exercise to understand the basics and implement it from scratch. I hadn't thought much about the boundary issue. Redis-backed token bucket sounds like a good next step to explore. Appreciate the suggestions!
Parsa Aftabi
Backend & Full-Stack Engineer — building high-performance systems and clean APIs. Go · TypeScript · React · PostgreSQL · Redis · Docker
Nice walkthrough. Two things worth adding for anyone taking this to production. Fixed-window counters have a boundary stampede problem: a burst at the end of one window plus a burst at the start of the next can double the intended rate. Sliding-window log or token bucket fixes it. The in-memory approach breaks the moment you run more than one replica, each instance gets its own budget. The standard production answer is a Redis-backed token bucket (a small Lua script keeps the check-and-decrement atomic). Happy to sketch it if useful.