---
title: "A Guide To API Rate Limiting In Django | CoderPad"
description: "API rate limiting is one of the most effective practices for improving security and preventing large spikes in API request calls, which can degrade overall performance. Learn how to efficiently manage requests to your API server in this article."
canonical: "https://coderpad.io/blog/development/a-guide-to-api-rate-limiting-in-django/"
last_modified: "2026-04-15 16:21:00"
---
[Back to blog](https://coderpad.io/blog/)

# A Guide To API Rate Limiting In Django

January 5, 2023 10 Minute Read

By Ubaydah Abdulwasiu

[Development](https://coderpad.io/blog/development/)

Imagine you’re driving on a busy highway during rush hour. As you approach a bottleneck in the road, you start to slow down and eventually come to a complete stop. Suddenly, a car comes speeding up behind you and tries to squeeze into the small gap between you and the car in front of you. The driver behind you is trying to bypass the traffic and get ahead, but their reckless behavior could potentially cause an accident. This is similar to the concept of rate limiting in the digital world. Just like how a bottleneck on a highway limits the number of cars that can pass through at a given time, rate limiting in technology limits the number of requests a server can handle in a specific timeframe to prevent overwhelming traffic and potential crashes.

API rate limiting is one of the most effective practices for improving security and preventing large spikes in API request calls, which can degrade overall performance.

In this article, we will discuss rate limiting and why it is essential, different types of rate limiting, rate-limiting implementation methods, and how we can implement throttling in Django.

## Objectives

By the end of this article, we should learn the following:

- Rate limiting and why it is important
- Different types of rate limiting
- Methods of implementing rate limiting
- How to implement rate limiting in Django

## What is rate limiting and why is it important?

Rate limiting is a technique used to control or limit the distribution or flow of traffic on an API in order to keep it from becoming overloaded and underperforming. API owners typically impose some control over their APIs by limiting the number of requests in a given time frame to ensure that clients use their resources fairly. This avoids an unnecessary spike in its traffic and improves web service scalability.

When developing applications with many users, API rate limiting is essential. It limits bot attacks to APIs and prevents [DoS attacks,](https://www.paloaltonetworks.com/cyberpedia/what-is-a-denial-of-service-attack-dos) in which a user launches many requests in seconds. Rate limiting can be used to ensure that API resources are not depleted and that legitimate users have proper access to the API.

Rate limiting is measured in requests per second, or RPS, which means that we can, for example, configure our API to allow three requests per minute from a specific user. When the user exceeds the limit, the API returns a`429`status code error, which means “Too Many Requests,” to notify the user that they have sent too many requests in the allotted time frame.

A server rate limiting requests

## Types Of rate limiting

Rate limiting can be used by defining different parameters based on the objectives and level of restriction desired. There are three major types of rate limiting, which we will go over in more detail below.

### User rate limiting

This type of rate limiting detects the number of requests made by a specific user and limits the user based on the restrictions set by the API developer. Many organizations use it as the most common type of rate limiting. It typically monitors a user’s IP address or API key and blocks additional requests if the limit is exceeded within the time frame specified until the rate-limiting period resets.

### Geographic-based rate limiting

This type of rate limiting limits the number of requests sent to the server from a specific region and location. This can be useful for reducing traffic spikes from a specific region, freeing up resources in the target regions.

### Server rate limiting

If different servers handle different parts of an application, rate limiting can be configured at the server level. This method allows developers to increase the rate limit on frequently used servers while decreasing the traffic limit on less regularly used servers, giving them more flexibility.

## Different methods of implementing rate limiting

Rate limiting can be implemented in various ways in an application. Below, we will go over some of the more general methods.

### Using request queues

Request queues limit the number of requests sent to an API in a given time frame. It is one of the most commonly used rate-limiting techniques. Numerous request libraries are available for various programming languages that make it simple to set rate-limiting for our API while doing most of the hard work for us. Service services such as Amazon Simple Queue Service can handle request and message queues.

### Throttling

Throttling is the process of putting the API into a temporary state to evaluate each request. A user may be disconnected or have a slower bandwidth when the throttle is triggered. It is a flexible rate-limiting method that can be applied at the user, API, or application level.

### Rate limiting algorithms

There are several algorithms to use when implementing rate limiting in a system. We will be discussing some of them below:

- Leaky Bucket: Leaky Bucket is a memory-efficient algorithm that queues and processes user requests using the FIFO (First In, First Out) method. It creates a queue with a specific capacity in a given time frame, processes each request in the queue in the order they arrive, and discards requests that arrive when the queue reaches its capacity in the given time frame. The leaky bucket algorithm makes it simple to regulate API requests and avoid traffic outbursts or spikes.
leaky bucket algorithm for rate limiting
- Token Bucket: Token Bucket is an algorithm that tracks individual users and the number of requests they make in a given period to limit them based on the quota set by the developer. When a user makes a request, the bucket containing the number of tokens the user has in the given time frame is checked, and if there are enough tokens, the request is processed, and a token is removed from the bucket. When the bucket’s tokens are depleted, the incoming request is rejected until the rate limiter is reset.
- Fixed window: Each user’s requests are given a fixed time window of n seconds in this algorithm. When a user requests within a specific time frame, a counter is incremented to keep track of how many requests the user is making. When the counter reaches the maximum number of requests for each window, the requests are discarded and not processed.
- Sliding window: This algorithm is similar to the fixed window algorithm, but the individual requests for a timestamp are not saved in this case. The sliding window will keep timestamps and a counter for requests that occur at the same time. This aids in the management of bursts of requests that occur at the same time and saves memory space.

## Implementing throttling in Django

Throttling is the same as permissions in the [Django Rest Framework](https://www.django-rest-framework.org/), as it determines whether a particular request should be authorized or discarded. It is used to rate-limit the number of API requests a client can make. Throttling is flexible in DRF, and multiple throttles can be implemented to control requests made by authenticated and anonymous users or to restrict resources based on different parts of the APIs.

Now let’s create an API and set some throttle policies.

### Project setup

To get started, we will set up a new [CoderPad Django sandbox](https://app.coderpad.io/sandbox). In the sandbox shell, install the`djangorestframework`library:

```
$ pip install djangorestframework
```

We then add the new app and`rest_framework`to the list of installed apps in`settings.py`and create a`urls.py`file for the app.

```
INSTALLED_APPS = ["django.contrib.admin",

    "django.contrib.auth",

    "django.contrib.contenttypes",

    "django.contrib.sessions",

    "django.contrib.messages",

    "django.contrib.staticfiles",

    "productApp",

    "rest_framework",

    "rest_framework.authtoken",     

]Code language: Python (python)
```

We will be having two`urls.py`files, one will be included in the project’s directory while the other in the`productApp`folder. Let’s create a new`urls.py`in the app’s directory and include it in the project’s own.

```
from django.contrib import admin

from django.urls import path, include

urlpatterns = [path("admin/", admin.site.urls), 

    path("products", include("productApp.urls"))

    ]Code language: Python (python)
```

In the app’s`urls.py`file, add the following code:

```
from django.urls import path

urlpatterns = []Code language: Python (python)
```

#### Creating models

With the project setup and routes pattern in place, let’s create a new model to add products to the database in the`models.py`file.

In`models.py`, add the following:

```
from django.db import models

class Product(models.Model):

    name = models.CharField(max_length=250)

    price = models.CharField(max_length=250)

    color = models.CharField(max_length=250)

    weight = models.CharField(max_length=250)Code language: Python (python)
```

In the code block above, we created a new class named`Product`by inheriting [Django’s model class](https://docs.djangoproject.com/en/4.1/topics/db/models/) which lets us define the fields and behaviors of the data we are storing. We then created the class attributes named`name`,`price`,`color`, and`weight`which map as database columns in our table.

Now, let’s migrate our fields to the database. In the command line, we’ll write the following commands to migrate our table to the database.

```
$ python manage.py makemigrations

Migrations for 'productApp':

  productApp/migrations/0001_initial.py

    - Create model Product

$ python manage.py migrate

Operations to perform:

  Apply all migrations: admin, auth, authtoken, contenttypes, polls, productApp, sessions

Running migrations:

  Applying authtoken.0001_initial... OK

  Applying authtoken.0002_auto_20160226_1747... OK

  Applying authtoken.0003_tokenproxy... OK

  Applying productApp.0001_initial... OKCode language: JavaScript (javascript)
```

In the next section, we will be creating a serializer for our model data.

#### Creating serializers

Let’s create a new file`serializers.py`in the`productApp`directory and add the following code:

```
from rest_framework import serializers

from .models import Product

class ProductSerializer(serializers.ModelSerializer):

    class Meta:

        model = Product

        fields = ["id", "name", "price", "color", "weight"]Code language: Python (python)
```

In the code block above, we created a new class for our model serializer. We then added a [Meta class,](https://www.datacamp.com/tutorial/python-metaclasses) which lets us define the model we are creating a serializer for and specify the fields of the models we want to output. Serialization in the Django Rest Framework helps us convert model objects into more flexible data types like JSON, which are more understandable by JavaScript and [frontend frameworks](https://coderpad.io/features/languages-and-frameworks/).

Now let’s head over to creating views and routes for our API.

#### Creating views and routes

In the previous sections, we created a model and serializer to format the output of our data properly. In this section, we will be creating a view for defining our API and a route.

In the`views.py`file in the app’s directory, add the following code:

```
from rest_framework.generics import CreateAPIView, ListAPIView, DestroyAPIView

from .models import Product

from .serializers import ProductSerializer

class CreateProduct(CreateAPIView):

    serializer_class = ProductSerializer

    queryset = Product.objects.all()

class GetProducts(ListAPIView):

    serializer_class = ProductSerializer

    queryset = Product.objects.all()

class DeleteProduct(DestroyAPIView):

    serializer_class = ProductSerializer

    queryset = Product.objects.all()Code language: Python (python)
```

In the code block above, we created views to create, get, and delete products using [generic views](https://www.django-rest-framework.org/api-guide/generic-views/#concrete-view-classes) in DRF. This lets us create basic CRUD (create, read, update, and delete) APIs to get and modify data in our database.

We then create the routes for our APIs in the app’s`urls.py`file.

```
from django.urls import path

from .views import CreateProduct, GetProducts, DeleteProduct

urlpatterns = [path("create", CreateProduct.as_view()),

    path("get", GetProducts.as_view()),

    path("delete", DeleteProduct.as_view()),

]Code language: Python (python)
```

In the code block above, we defined routes for our API views created earlier, which let us map to proper resources when requested on our browser.

Now let’s define some throttling policies for our API globally.

>

💡 The Django REST framework (DRF) provides several classes for implementing throttling in a Django application. These classes are located in the`rest_framework.throttling`module.

In the`settings.py`file, we will be adding some throttling classes that will tell Django to throttle our APIs according to the policies we set.

```
REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle',

        'rest_framework.throttling.UserRateThrottle'

    ],

    'DEFAULT_THROTTLE_RATES': {

        'anon': '2/min',

        'user': '4/min'

    }

}Code language: Python (python)
```

In the code block above, we defined some throttling classes named`UserRateThrottle`and`AnonRateThrottle`. The`UserRateThrottle`throttles the requests of authenticated users in the app by using the user ID to generate a unique key to throttle against, while the`AnonRateThrottle`throttles the requests of unconfirmed or unauthenticated users in the app by using the IP address to generate a unique key to throttle against.

The`DEFAULT_THROTTLE_RATES`sets the number of requests per period for each type of user. The period can be`minute`,`second`,`hour`, or`day`.

To test this, let’s try the create product endpoint and attempt to create a new product more than twice in the same minute. In the sandbox shell, execute the request:

```
curl --location --request POST 'http://0.0.0.0:3000/products/create' \

--header 'Content-Type: application/json' \

--data-raw '{

    "name": "Foodco",

    "price": "3000",

    "color": "blue",

    "weight": "32kg"

}'Code language: Python (python)
```

In the code block above, we made a request to create a product.

When we try the create product endpoint for the third time in the same minute, we will get a`429`too many requests error code and the response shown below.

```
​​{"detail":"Request was throttled. Expected available in 58 seconds."}Code language: JSON / JSON with Comments (json)
```

The throttle classes can also be defined on each view. For example, we can rewrite the`CreateProduct`view and specify the throttle class.

```
from rest_framework.throttling import UserRateThrottle

class CreateProduct(CreateAPIView):

    throttle_classes = [UserRateThrottle]

    serializer_class = ProductSerializer

    queryset = Product.objects.all()Code language: Python (python)
```

In the code above, we defined the throttle class on the`CreateProduct`view by adding it as an attribute.

### Multiple user rate throttle

We may want to set different throttling policies for an API. To accomplish this, we define multiple user rate throttles for users by overriding the default throttle class and adding a scope value that will be used to identify them when defining the throttle rate.

Let’s create a new file in the app’s directory named`throttles.py`.

In`throttles.py`, let’s add the following code:

```
from rest_framework.throttling import UserRateThrottle

class HighRateThrottle(UserRateThrottle):

    scope = 'high'

class LowRateThrottle(UserRateThrottle):

    scope = 'low'Code language: Python (python)
```

We will change the`settings.py`file to the new throttle classes defined:

```
REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_CLASSES': ['productApp.throttles.HighRateThrottle',

        'productApp.throttles.LowRateThrottle',

    ],

    'DEFAULT_THROTTLE_RATES': {

        'high': '30/minute',

        'low': '4/minute'

    }

}Code language: Python (python)
```

In the code block above, we override the`UserRateThrottle`class and define two new throttles to handle requests based on the policies set. The high-rate throttle will handle more requests in a minute than the low-rate throttle.

### Scoped rate throttle

We may want to limit access to some APIs while increasing access to others. This is accomplished by setting the default throttle class to`ScopedRateThrottle`and including a ‘throttle scope’ property in our view.

For example, let’s override our throttle settings in the`settings.py`file.

```
REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_CLASSES': ["rest_framework.throttling.ScopedRateThrottle"

    ],

    'DEFAULT_THROTTLE_RATES': {

        'high': '30/day’,

        'low': '4/day'

    }

}Code language: PHP (php)
```

Then, in our view, we define the throttle scope for each view:

```
from rest_framework.generics import CreateAPIView, ListAPIView, DestroyAPIView

from .models import Product

from .serializers import ProductSerializer

class CreateProduct(CreateAPIView):

    throttle_scope = "low"

    serializer_class = ProductSerializer

    queryset = Product.objects.all()

class GetProducts(ListAPIView):

    throttle_scope = "high"

    serializer_class = ProductSerializer

    queryset = Product.objects.all()

class DeleteProduct(DestroyAPIView):

    throttle_scope = "low"

    serializer_class = ProductSerializer

    queryset = Product.objects.all()Code language: Python (python)
```

We defined a`throttle_scope`in the code block above for each view. The user requests on the endpoint to`create`and`delete`products will be restricted to 4 per day, while the user requests to`get`products will be as high as 30 per day.

Test the request rate limiter built in this article in the sandbox below:

## Conclusion

In this article, we have discussed rate limiting and why it is essential. We also discussed the different types of rate limiting, which include user rate limiting, geographic-based rate limiting, and server rate limiting. We then discussed how to implement rate limiting using various methods, including throttling, request queues, and different rate-limiting algorithms. In the last part of the article, we created an API in the Django Rest Framework and explained how to set throttling on the APIs using different throttling classes, giving us a better understanding of how rate limiting works and how we can use it in Django Rest Framework APIs.

Ubaydah is a backend developer experienced in building APIs and writing documentation. She loves sharing technical knowledge in form of articles to educate others.

## Subscribe for more CoderPad insights

## Trending Articles

Previous slide Next slide [Development

## What is Prompt Engineering?

Introducing AI tools such as ChatGPT and Bard helps increase the efficiency of tasks such as data generation, code generation and completion, text summarization, etc. How were these AI tools trained to answer almost every question you ask them? The answer, prompt engineering, is discussed in this blog post.

Read the post](https://coderpad.io/blog/development/what-is-prompt-engineering/) [Development

## A Guide To Using React’s useCallback() Hook

Are you looking to optimize your React applications? Have you heard of the useCallback hook? useCallback is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. In this post, we'll dive into React's useCallback() hook, define referential equality and callback functions and how to tie it all together.

Read the post](https://coderpad.io/blog/development/a-guide-to-using-reacts-usecallback-hook/) [Development

## MySQL vs. PostgreSQL: How Do They Compare?

A database is a convenient tool that allows users to access information, maintain records, and apply commonly used operations, such as insertion, modification, deletion, and data organization. Learn about MySQL vs PostgreSQL, their features, advantages, and disadvantages. Finally, check out which one is the best choice for you.

Read the post](https://coderpad.io/blog/development/mysql-vs-postgresql-how-do-they-compare/) [Development

## PostgreSQL LIKE Operator: A Detailed Guide

When using databases, searching for values that match a given pattern is a familiar necessity. Learn how you can retrieve entries with queries including a particular string using Postgres LIKE operator.

Read the post](https://coderpad.io/blog/development/postgresql-like-operator-a-detailed-guide/) [Development

## How To Use DataProvider In TestNG With Examples

When it comes to testing there are many tools and techniques available. In this post, we'll discuss how to use DataProvider with TestNG.

Read the post](https://coderpad.io/blog/development/how-to-use-dataprovider-in-testng-with-examples/) [Development

## How To Get Up And Running With Django Migrations: A Guide

Django migrations are a way of handling the application of changes to a database schema. By following the steps outlined in this guide, you can easily set up and use migrations in your Django projects.

Read the post](https://coderpad.io/blog/development/how-to-get-up-and-running-with-django-migrations-a-guide/) [Development

## Writing A Parameterized Test In JUnit With Examples

A JUnit parameterized test allows you to decouple data from structure, generating cleaner and more reliable tests. Learn more in this guide.

Read the post](https://coderpad.io/blog/development/writing-a-parameterized-test-in-junit-with-examples/) [Development

## How To Use Assert In JUnit With Examples

The JUnit Assert class is what you use to write unit testing assertions in JUnit. Learn more about it in this guide, full of examples.

Read the post](https://coderpad.io/blog/development/how-to-use-assert-in-junit-with-examples/) [Development

## A Simple Guide To TypeORM: What It Is And How To Use It

Considering current languages have object-oriented programming features, most database management systems are based on the relational model, with tables instead of objects. For these reasons, mapping relational objects is very important in development. In this article, you will learn what TypeORM, one of the main tools used today, is.

Read the post](https://coderpad.io/blog/development/a-simple-guide-to-typeorm-what-it-is-and-how-to-use-it/) [Development

## Using PreparedStatement in JDBC With Examples

In this post, we'll see why and how to work with JDBC and PreparedStatement. We will also learn along with examples using code.

Read the post](https://coderpad.io/blog/development/using-preparedstatement-in-jdbc-with-examples/) [Development

## React vs React Native: The Differences Explained

React and React Native are similar in that they both allow web developers to build applications based on the unique concept of components. But the two frameworks do this in radically different ways. In this post, we cover the key differences between react and react native frameworks, implementation, and which is an appropriate choice.

Read the post](https://coderpad.io/blog/development/react-vs-react-native-the-differences-explained/) [Development

## Logging in Django

The most challenging part of fixing a problem is identifying it. Unfortunately, this statement is exceptionally true when it comes to debugging. Learn how to use the power of logging into your Django applications to improve your debug process in this article.

Read the post](https://coderpad.io/blog/development/logging-in-django/)

## Hire with confidence.

See why engineering teams trust CoderPad to evaluate developers with realistic, AI-ready hiring workflows.

[Request a demo](https://coderpad.io/sales/)
