How to build a Rate Limiter using Redis

Author: Ajeet Singh Raina

Rate limiting is a mechanism that many developers may have to deal with at some point in their life. It’s useful for a variety of purposes like sharing access to limited resources or limiting the number of requests made to an API endpoint and responding with a 429 status code.

In this tutorial, we will see how to implement Rate Limiting using various programming languages:

Using Python#

Step 1. Pre-requisite#

  • Python
  • Docker
  • Docker Compose

Step 2. Clone the repository#

git clone https://github.com/redis-developer/basic-rate-limiting-demo-python

Step 3. Run docker compose or install redis manually#

docker network create global
docker-compose up -d --build

If you install redis manually open django-backend/configuration folder and copy .env.example to create .env. And provide the values for environment variables

- REDIS_HOST: Redis server host
- REDIS_PORT: Redis server port
- REDIS_DB: Redis server db index
- REDIS_PASSWORD: Redis server password

Step 4. Setup and run#

Install python, pip and venv (on mac: https://installpython3.com/mac/)

Use python version: 3.8

python3 -m venv venv
source ./venv/bin/activate
pip3 install -r requirements.txt
python3 manage.py collectstatic
python3 manage.py runserver

Step 5. Accessing the rate limiting app

Rate Limiting

How it works?#

How the data is stored:#

This app will block connections from a client after surpassing certain amount of requests (default: 10) per time (default: 10 sec) The application will return after each request the following headers. That will let the user know how many requests they have remaining before the run over the limit. On the 10th run server should return an HTTP status code of 429 Too Many Requests

SETNX is short for "SET if Not eXists". It basically sets key to hold string value if key does not exist. In that case, it is equal to SET. When key already holds a value, no operation is performed. New responses are added key-ip as shown below:

SETNX your_ip:PING limit_amount
Example: SETNX 127.0.0.1:PING 10

More information

Set a timeout on key:

EXPIRE your_ip:PING timeout
Example: EXPIRE 127.0.0.1:PING 1000

More information

How the data is accessed:#

Next responses are get bucket:

GET your_ip:PING
Example: GET 127.0.0.1:PING

More information

Next responses are changed bucket:

DECRBY your_ip:PING amount
Example: DECRBY 127.0.0.1:PING 1

More information

References#