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.