← All projects
Backend / Systems· Production & Systems· Built· Mar 2026

Limitron

A rate limiter written as Express middleware. It uses a sliding-window log in Redis and sets per-API-key limits by tier.

rate:<api-key or ip> · sorted set, score = Date.now()window_secondsnowZREMRANGEBYSCORE0 … now − windowZADDZCARDcount < max_requests→ 200 · X-RateLimit-Remainingotherwise→ 429 · Retry-After (oldest entry + window − now)

Overview

Limitron sits in front of /api/* routes and throttles each API key (or IP when there's no key). Nginx and cloud gateways do this for you, but I wanted to build the algorithm myself and see how it actually works.

Problem

Without a limit, one client can flood an API. Fixed windows (say, reset every minute) let clients burst at the edges, so I went with a sliding window instead.

Approach

Every request is a timestamp in a Redis sorted set per client. On each request I remove timestamps older than the window (ZREMRANGEBYSCORE), count what's left (ZCARD), and either add the new one (ZADD) or reject with 429. Limits come from tiers stored in Redis hashes, so changing a key's plan doesn't need a deploy.

Architecture / how it works

  • Sorted-set members are randomUUID()s with Date.now() as the score, so two requests in the same millisecond don't collide.
  • apikey:<key> maps to a tier name, and tier:<name> holds max_requests and window_seconds.
  • Every response gets X-RateLimit-Limit/Remaining/Reset. On a 429 it adds Retry-After, calculated from the oldest entry in the window.
  • Mounted as app.use('/api', limiter, router), so admin routes aren't throttled.
  • GET /api/status shows how much of your window you've used without using up a request.
  • Honest gap: prune, count and add are separate Redis calls, so two requests at the exact same moment can both get through. Wrapping them in MULTI or a Lua script (like I did in LockForge) would fix it.

Tech stack

TypeScriptNode.jsExpressRedisioredisDocker

Outcomes

It runs with Docker Compose next to redis:7-alpine, and the headers use the same X-RateLimit-* style as GitHub's API.

Resume

Want my resume?

I share it on request, so you always get the latest version. Drop me an email with a line about the role or why you're asking, and I'll send it over.

devanshpandeyji4321@gmail.com
Write the email →