Get Started

Build a rate limiter and API gateway that holds up

Put a gateway in front of a service that checks the API key, forwards the request, and counts how fast each caller is going. Add a token-bucket limiter backed by Redis, load-test it, and watch the excess requests come back as a real 429 with a Retry-After header. Then run two gateways against one Redis and see the limit still hold, which is the whole reason the counter lives in Redis and not in memory.

115 minAdvancedTools: Free. Everything runs on your own PC. Redis runs in a container; the gateway and backend are a few dozen lines of Python each.Step 1 free
Tested 12 Oct 2026 · Windows 11 with WSL2 (Ubuntu), Docker Engine 29.1.3, Python 3.12, FastAPI 0.120.4, uvicorn 0.38.0, httpx 0.28.1, redis-py 6.4.0, Redis 7.4.1. Gateway, backend and Redis all on one machine. No GPU.
A working API gateway in front of a backend that checks an API key, forwards the request, and enforces a token-bucket limit held in Redis, so the limit survives a restart and holds across more than one gateway process
A real load testfire 100 requests at a limit of 20, watch about 20 return 200 and the rest return 429 with a correct Retry-After, see two API keys limited independently, and measure the limiter's latency cost
A starter kit with the backend, the gateway, the limiter, a docker-compose for Redis, the load-test script and a deliberately broken in-memory version that shows why shared state matters
Before you start
  • Level 0 done: Install anything from GitHub, safely and The terminal survival kit.
  • Build your own API in Python, or equivalent comfort with FastAPI, uv/pip and running a local server. This mission builds a gateway in the same style and assumes you have met FastAPI, dependencies and JSON responses before.
  • Docker without fear for Docker and docker compose. Redis runs in a container; you do not install it on your machine.
  • Some comfort with the terminal and three windows open at once. A code editor. About 400MB of disk for the Redis image and the Python packages.
01/07What a gateway does, and why rate limit at all0 done
STEP 01 of 07~10 min

What a gateway does, and why rate limit at all

Before any code, get the shape of the problem clear: what sits where, and what you are protecting against.

  1. An API gateway is a single front door. Every request to your service goes through it first, and it decides what happens next: is the caller allowed in, which backend should answer, and has this caller had more than its share. Because it forwards the request on to another server and returns that server's reply, it is also a reverse proxy (a proxy that stands in front of your own servers, as opposed to one that stands in front of a browser). The backend behind it can then stay simple and private: it trusts that anything reaching it has already been checked.

  2. Rate limiting is capping how many requests a caller may make in a window of time. Without it, one script in a loop, one scraper, or one bug that retries forever can use all your capacity, and everyone else gets slow answers or none. A limit protects the backend from being overwhelmed, keeps one noisy caller from starving the rest, and puts a ceiling on cost when each request does real work.

  3. When a caller is over the limit, the gateway does not forward the request. It answers straight away with 429 Too Many Requests, the HTTP status that means "slow down". A good 429 carries a Retry-After header saying how many seconds to wait. This is backpressure: the server telling the client to ease off, instead of quietly falling over. A well-behaved client reads Retry-After and waits; a badly-behaved one at least does no more damage, because its requests are refused cheaply at the door.

    • The caller sends a request with an API key.
    • The gateway checks the key. No key or a wrong one gets 401 and stops here.
    • The gateway checks the limit for that key. Over the limit gets 429 with Retry-After and stops here.
    • Otherwise the gateway forwards the request to the backend and returns the backend's reply.
  4. You will build exactly that, smallest piece first: the backend, then the gateway with the key check and routing, then the limiter, then the load test that proves it works, then a second gateway to show the limit holds across processes.

✓
CheckpointYou can say, in one sentence each, what a gateway is, what rate limiting protects against, and what a 429 with Retry-After tells the caller.
If it breaksIs a gateway the same as a load balancer? + 1 more
Is a gateway the same as a load balancer?
They overlap. A load balancer spreads traffic across copies of a backend. A gateway adds policy: authentication, rate limiting, routing by path, request logging. Many real gateways do both. Here the focus is the policy, specifically rate limiting.
Why not rate limit inside the backend itself?
You can, but then every backend has to carry the same code and share the same counter. Putting it in the gateway means one place to change the rules, and the backend stays a plain service. It also refuses excess traffic before it reaches the backend at all.
Still stuck? Ask the community
Next mission · Advanced buildsRun background jobs properly with a task queue
→