Rate Limiting

Last updated 8 months ago

Introduction

In order to make your API scalable you can do two things: add infrastructure to it (more servers, instances, databases, etc) or you can add rate limiting. Rate limiting is the act of limiting the number of requests a certain resource should accept from a given user (typically an IP address).

Getting Started

Adding rate limiting is done by inheriting from a single class and specifying a new attribute. Simply import the RateLimit class and add it to your resource:

from entry.api.Resource import Resource
from entry.api.JsonSerialize import JsonSerialize
from entry.api.RateLimit import RateLimit
from app.User import User
class UserResource(Resource, JsonSerialize, RateLimit):
model = User

Once that's done we now have to specify our rate limit. A rate limit is a class attribute that is declared as a tuple with three arguments:

rate_limit = (num_of_requests, time_length, time_type)

Inside a resource will look like:

from entry.api.Resource import Resource
from entry.api.JsonSerialize import JsonSerialize
from entry.api.RateLimit import RateLimit
from app.User import User
class UserResource(Resource, JsonSerialize, RateLimit):
model = User
rate_limit = (1000, 1, 'minute')

This can be read as "limit this resource to 1000 requests every 1 minute." This of course is based on a single IP address If the rate limit is not specified then it will default to a rate limit of 100 requests per minute.

Most rate limit time periods are usually every minute but some can be more customized. For example, Twitter's rate limits are reset every 15 minutes. If you wanted a rate limit that is reset every 15 minutes like Twitter then you can do:

from entry.api.Resource import Resource
from entry.api.JsonSerialize import JsonSerialize
from entry.api.RateLimit import RateLimit
from app.User import User
class UserResource(Resource, JsonSerialize, RateLimit):
model = User
rate_limit = (1000, 15, 'minutes')

Time Options

Rate limits can have a singular or plural time type and can look like any of the following.

Notice the difference here between singular and plural. This is implemented to improve the readability of the syntax. Feel free to use which ever one you like. In other words, rate_limit = (1000, 15, 'minutes') (plural) will work exactly the same as rate_limit = (1000, 15, 'minute') (singular).

rate_limit = (1000, 1, 'second')
rate_limit = (1000, 10, 'minutes')
rate_limit = (1000, 10, 'hours')
rate_limit = (1000, 10, 'days')
rate_limit = (1000, 10, 'months')
rate_limit = (1000, 10, 'years')

Headers

When you are using the RateLimit class, there will be new headers that are sent on all of your server endpoint responses. These headers are:

X-RateLimit-Limit
X-RateLimit-Remaining

These headers will have the corresponding integer associated with them. For example:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 928

These rate limits are in association with the current period (minute, hour, days etc). This period will not be known to the developer through these headers so they will have to consult your documentation for what the period is.

You can use these headers on your front end to let the user know how many requests they have left or even make accommodations like improved caching or not sending certain low priority requests