Skip to content

Backend workshop · 7 chapters · 91 minutes

Rate limits from scratch.

One busy client should not take your API down for everyone. Build three rate limiters in plain Python, put them in front of a real HTTP server, break them on purpose, and write the client that backs off politely.

  • No dependencies: Python standard library only.
  • A simulator with a fake clock: replay traffic in milliseconds.
  • A real server answering 429 with Retry-After, and a hammer to test it.
  • Every chapter ends with an exercise and a way to check it.
python -m limits simulatelimit 10 per second
20 requests between 0.90s and 1.09s limiter allowed worst 1s
none 20 20
fixed-window 20 20
sliding-log 10 10
token-bucket 11 11
The fixed window let twice the limit through.

What you build

Fixed windowlab/limits/fixed_window.pyA counter per second. Simple, with a hole.
Sliding loglab/limits/sliding_log.pyExact over any second, paid for in memory.
Token bucketlab/limits/token_bucket.pyBursts on purpose, a steady average.
Polite clientlab/limits/client.pyBackoff, jitter and Retry-After.

7 short chapters

Each one is a few minutes of reading, one thing to run, and an exercise. By the end you can pick a limiter, a key and a limit for a real API, and explain why.

  1. 01Why rate limits10 min
  2. 02Fixed window15 min
  3. 03Sliding log12 min
  4. 04Token bucket15 min
  5. 05Say no properly: HTTP 42912 min
  6. 06Retry politely15 min
  7. 07Test it, then ship it12 min

Run it in a minute

You need uv and git. uv installs Python for you.

git clone https://github.com/jars-demo/rate-limit-demo.git
cd rate-limit-demo/lab
uv sync
uv run python -m limits simulate